A Discrete-Event Network Simulator
API
sixlowpan-net-device.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013 Universita' di Firenze, Italy
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: Tommaso Pecorella <tommaso.pecorella@unifi.it>
19  * Michele Muccio <michelemuccio@virgilio.it>
20  */
21 
22 #include "ns3/node.h"
23 #include "ns3/channel.h"
24 #include "ns3/packet.h"
25 #include "ns3/log.h"
26 #include "ns3/boolean.h"
27 #include "ns3/abort.h"
28 #include "ns3/simulator.h"
29 #include "ns3/uinteger.h"
30 #include "ns3/icmpv6-header.h"
31 #include "ns3/ipv6-header.h"
32 #include "ns3/mac16-address.h"
33 #include "ns3/mac48-address.h"
34 #include "ns3/mac64-address.h"
35 #include "ns3/unused.h"
36 #include "ns3/ipv6-l3-protocol.h"
37 #include "ns3/ipv6-extension-header.h"
38 #include "ns3/udp-header.h"
39 #include "ns3/udp-l4-protocol.h"
40 #include "sixlowpan-net-device.h"
41 #include "sixlowpan-header.h"
42 
43 NS_LOG_COMPONENT_DEFINE ("SixLowPanNetDevice");
44 
45 namespace ns3 {
46 
47 NS_OBJECT_ENSURE_REGISTERED (SixLowPanNetDevice);
48 
50 {
51  static TypeId tid = TypeId ("ns3::SixLowPanNetDevice")
52  .SetParent<NetDevice> ()
53  .AddConstructor<SixLowPanNetDevice> ()
54  .AddAttribute ("Rfc6282", "Use RFC6282 (IPHC) if true, RFC4944 (HC1) otherwise.",
55  BooleanValue (true),
58  .AddAttribute ("OmitUdpChecksum",
59  "Omit the UDP checksum in IPHC compression.",
60  BooleanValue (true),
63  .AddAttribute ("FragmentReassemblyListSize", "The maximum size of the reassembly buffer (in packets). Zero meaning infinite.",
64  UintegerValue (0),
66  MakeUintegerChecker<uint16_t> ())
67  .AddAttribute ("FragmentExpirationTimeout",
68  "When this timeout expires, the fragments will be cleared from the buffer.",
69  TimeValue (Seconds (60)),
71  MakeTimeChecker ())
72  .AddAttribute ("CompressionThreshold",
73  "The minimum MAC layer payload size.",
74  UintegerValue (0x0),
76  MakeUintegerChecker<uint32_t> ())
77  .AddAttribute ("ForceEtherType",
78  "Force a specific EtherType in L2 frames.",
79  BooleanValue (false),
82  .AddAttribute ("EtherType",
83  "The specific EtherType to be used in L2 frames.",
84  UintegerValue (0xFFFF),
86  MakeUintegerChecker<uint16_t> ())
87  .AddTraceSource ("Tx",
88  "Send - packet (including 6LoWPAN header), "
89  "SixLoWPanNetDevice Ptr, interface index.",
91  "ns3::SixLowPanNetDevice::RxTxTracedCallback")
92  .AddTraceSource ("Rx",
93  "Receive - packet (including 6LoWPAN header), "
94  "SixLoWPanNetDevice Ptr, interface index.",
96  "ns3::SixLowPanNetDevice::RxTxTracedCallback")
97  .AddTraceSource ("Drop",
98  "Drop - DropReason, packet (including 6LoWPAN header), "
99  "SixLoWPanNetDevice Ptr, interface index.",
101  "ns3::SixLowPanNetDevice::DropTracedCallback")
102  ;
103  return tid;
104 }
105 
107  : m_node (0),
108  m_netDevice (0),
109  m_ifIndex (0)
110 {
111  NS_LOG_FUNCTION (this);
112  m_netDevice = 0;
113  m_rng = CreateObject<UniformRandomVariable> ();
114 }
115 
117 {
118  NS_LOG_FUNCTION (this);
119  return m_netDevice;
120 }
121 
123 {
124  NS_LOG_FUNCTION (this << device);
125  m_netDevice = device;
126 
127  NS_LOG_DEBUG ("RegisterProtocolHandler for " << device->GetInstanceTypeId ().GetName ());
128 
129  uint16_t protocolType = 0;
130  if ( m_forceEtherType )
131  {
132  protocolType = m_etherType;
133  }
135  this),
136  protocolType, device, false);
137 }
138 
139 int64_t SixLowPanNetDevice::AssignStreams (int64_t stream)
140 {
141  NS_LOG_FUNCTION (this << stream);
142  m_rng->SetStream (stream);
143  return 1;
144 }
145 
147 {
148  NS_LOG_FUNCTION (this);
149 
150  m_netDevice = 0;
151  m_node = 0;
152 
153  for (MapFragmentsTimersI_t iter = m_fragmentsTimers.begin (); iter != m_fragmentsTimers.end (); iter++)
154  {
155  iter->second.Cancel ();
156  }
157  m_fragmentsTimers.clear ();
158 
159  for (MapFragmentsI_t iter = m_fragments.begin (); iter != m_fragments.end (); iter++)
160  {
161  iter->second = 0;
162  }
163  m_fragments.clear ();
164 
166 }
167 
169  Ptr<const Packet> packet,
170  uint16_t protocol,
171  Address const &src,
172  Address const &dst,
173  PacketType packetType)
174 {
175  NS_LOG_FUNCTION (this << incomingPort << packet << protocol << src << dst);
176  NS_LOG_DEBUG ("UID is " << packet->GetUid ());
177 
178  uint8_t dispatchRawVal = 0;
179  SixLowPanDispatch::Dispatch_e dispatchVal;
180  Ptr<Packet> copyPkt = packet->Copy ();
181 
183 
184  copyPkt->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
185  dispatchVal = SixLowPanDispatch::GetDispatchType (dispatchRawVal);
186  bool isPktDecompressed = false;
187  bool fragmented = false;
188 
189  NS_LOG_DEBUG ( "Packet received: " << *copyPkt );
190  NS_LOG_DEBUG ( "Packet length: " << copyPkt->GetSize () );
191  NS_LOG_DEBUG ( "Dispatches: " << int(dispatchRawVal) << " - " << int(dispatchVal) );
192 
193  if ( dispatchVal == SixLowPanDispatch::LOWPAN_FRAG1 )
194  {
195  isPktDecompressed = ProcessFragment (copyPkt, src, dst, true);
196  fragmented = true;
197  }
198  else if ( dispatchVal == SixLowPanDispatch::LOWPAN_FRAGN )
199  {
200  isPktDecompressed = ProcessFragment (copyPkt, src, dst, false);
201  fragmented = true;
202  }
203  if ( fragmented )
204  {
205  if ( !isPktDecompressed )
206  {
207  return;
208  }
209  else
210  {
211  copyPkt->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
212  dispatchVal = SixLowPanDispatch::GetDispatchType (dispatchRawVal);
213  }
214  }
215 
216  switch ( dispatchVal )
217  {
219  NS_LOG_DEBUG ("Unsupported 6LoWPAN encoding: MESH, dropping.");
221  break;
223  NS_LOG_DEBUG ("Unsupported 6LoWPAN encoding: BC0, dropping.");
225  break;
227  NS_LOG_DEBUG ( "Packet without compression. Length: " << copyPkt->GetSize () );
228  {
229  SixLowPanIpv6 uncompressedHdr;
230  copyPkt->RemoveHeader(uncompressedHdr);
231  isPktDecompressed = true;
232  }
233  break;
235  DecompressLowPanHc1 (copyPkt, src, dst);
236  isPktDecompressed = true;
237  break;
239  DecompressLowPanIphc (copyPkt, src, dst);
240  isPktDecompressed = true;
241  break;
242  default:
243  NS_LOG_DEBUG ("Unsupported 6LoWPAN encoding: dropping.");
245  break;
246  }
247 
248  if ( !isPktDecompressed )
249  {
250  return;
251  }
252 
253  NS_LOG_DEBUG ( "Packet decompressed length: " << copyPkt->GetSize () );
254  NS_LOG_DEBUG ( "Packet decompressed received: " << *copyPkt );
255 
256  if (!m_promiscRxCallback.IsNull ())
257  {
258  m_promiscRxCallback (this, copyPkt, Ipv6L3Protocol::PROT_NUMBER, src, dst, packetType);
259  }
260 
261  m_rxCallback (this, copyPkt, Ipv6L3Protocol::PROT_NUMBER, src);
262 
263  return;
264 }
265 
266 void SixLowPanNetDevice::SetIfIndex (const uint32_t index)
267 {
268  NS_LOG_FUNCTION (this << index);
269  m_ifIndex = index;
270 }
271 
272 uint32_t SixLowPanNetDevice::GetIfIndex (void) const
273 {
274  NS_LOG_FUNCTION (this);
275  return m_ifIndex;
276 }
277 
279 {
280  NS_LOG_FUNCTION (this);
281  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
282 
283  return m_netDevice->GetChannel ();
284 }
285 
287 {
288  NS_LOG_FUNCTION (this << address);
289  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
290 
291  m_netDevice->SetAddress (address);
292 }
293 
295 {
296  NS_LOG_FUNCTION (this);
297  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
298 
299  return m_netDevice->GetAddress ();
300 }
301 
302 bool SixLowPanNetDevice::SetMtu (const uint16_t mtu)
303 {
304  NS_LOG_FUNCTION (this << mtu);
305  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
306 
307  return m_netDevice->SetMtu (mtu);
308 }
309 
310 uint16_t SixLowPanNetDevice::GetMtu (void) const
311 {
312  NS_LOG_FUNCTION (this);
313 
314  uint16_t mtu = m_netDevice->GetMtu ();
315 
316  // RFC 4944, section 4.
317  if (mtu < 1280)
318  {
319  mtu = 1280;
320  }
321  return mtu;
322 }
323 
325 {
326  NS_LOG_FUNCTION (this);
327  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
328 
329  return m_netDevice->IsLinkUp ();
330 }
331 
333 {
334  NS_LOG_FUNCTION (this);
335  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
336 
337  return m_netDevice->AddLinkChangeCallback (callback);
338 }
339 
341 {
342  NS_LOG_FUNCTION (this);
343  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
344 
345  return m_netDevice->IsBroadcast ();
346 }
347 
349 {
350  NS_LOG_FUNCTION (this);
351  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
352 
353  return m_netDevice->GetBroadcast ();
354 }
355 
357 {
358  NS_LOG_FUNCTION (this);
359  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
360 
361  return m_netDevice->IsMulticast ();
362 }
363 
365 {
366  NS_LOG_FUNCTION (this << multicastGroup);
367  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
368 
369  return m_netDevice->GetMulticast (multicastGroup);
370 }
371 
373 {
374  NS_LOG_FUNCTION (this << addr);
375  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
376 
377  return m_netDevice->GetMulticast (addr);
378 }
379 
381 {
382  NS_LOG_FUNCTION (this);
383  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
384 
385  return m_netDevice->IsPointToPoint ();
386 }
387 
389 {
390  NS_LOG_FUNCTION (this);
391  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
392 
393  return m_netDevice->IsBridge ();
394 }
395 
397  const Address& dest,
398  uint16_t protocolNumber)
399 {
400  NS_LOG_FUNCTION (this << *packet << dest << protocolNumber);
401  bool ret = false;
402  Address src;
403 
404  ret = DoSend (packet, src, dest, protocolNumber, false);
405  return ret;
406 }
407 
409  const Address& src,
410  const Address& dest,
411  uint16_t protocolNumber)
412 {
413  NS_LOG_FUNCTION (this << *packet << src << dest << protocolNumber);
414  bool ret = false;
415 
416  ret = DoSend (packet, src, dest, protocolNumber, true);
417  return ret;
418 }
419 
421  const Address& src,
422  const Address& dest,
423  uint16_t protocolNumber,
424  bool doSendFrom)
425 {
426  NS_LOG_FUNCTION (this << *packet << src << dest << protocolNumber << doSendFrom);
427  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
428 
429  Ptr<Packet> origPacket = packet->Copy ();
430  uint32_t origHdrSize = 0;
431  uint32_t origPacketSize = packet->GetSize ();
432  bool ret = false;
433 
434  if (m_forceEtherType)
435  {
436  protocolNumber = m_etherType;
437  }
438 
439  if (m_useIphc)
440  {
441  origHdrSize += CompressLowPanIphc (packet, m_netDevice->GetAddress (), dest);
442  }
443  else
444  {
445  origHdrSize += CompressLowPanHc1 (packet, m_netDevice->GetAddress (), dest);
446  }
447 
448  if ( packet->GetSize () > m_netDevice->GetMtu () )
449  {
450  NS_LOG_LOGIC ("Fragmentation: Packet size " << packet->GetSize () << " - Mtu " << m_netDevice->GetMtu () );
451  // fragment
452  std::list<Ptr<Packet> > fragmentList;
453  DoFragmentation (packet, origPacketSize, origHdrSize, fragmentList);
454  std::list<Ptr<Packet> >::iterator it;
455  bool success = true;
456  for ( it = fragmentList.begin (); it != fragmentList.end (); it++ )
457  {
458  NS_LOG_DEBUG ( "SixLowPanNetDevice::Send (Fragment) " << **it );
460  if (doSendFrom)
461  {
462  success &= m_netDevice->SendFrom (*it, src, dest, protocolNumber);
463  }
464  else
465  {
466  success &= m_netDevice->Send (*it, dest, protocolNumber);
467  }
468  }
469  ret = success;
470  }
471  else
472  {
473  if (packet->GetSize () < m_compressionThreshold)
474  {
475  NS_LOG_LOGIC ("Compressed packet too short, using uncompressed one");
476  packet = origPacket;
477  SixLowPanIpv6 ipv6UncompressedHdr;
478  packet->AddHeader (ipv6UncompressedHdr);
479  }
480 
482  if (doSendFrom)
483  {
484  NS_LOG_DEBUG ( "SixLowPanNetDevice::SendFrom " << m_node->GetId () << " " << *packet );
485  ret = m_netDevice->SendFrom (packet, src, dest, protocolNumber);
486  }
487  else
488  {
489  NS_LOG_DEBUG ( "SixLowPanNetDevice::Send " << m_node->GetId () << " " << *packet );
490  ret = m_netDevice->Send (packet, dest, protocolNumber);
491  }
492  }
493 
494  return ret;
495 }
496 
498 {
499  NS_LOG_FUNCTION (this);
500  return m_node;
501 }
502 
504 {
505  NS_LOG_FUNCTION (this << node);
506  m_node = node;
507 }
508 
510 {
511  NS_LOG_FUNCTION (this);
512  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
513 
514  return m_netDevice->NeedsArp ();
515 }
516 
518 {
519  NS_LOG_FUNCTION (this << &cb);
520  m_rxCallback = cb;
521 }
522 
524 {
525  NS_LOG_FUNCTION (this << &cb);
526  m_promiscRxCallback = cb;
527 }
528 
530 {
531  NS_LOG_FUNCTION (this);
532  return true;
533 }
534 
535 uint32_t
537 {
538  NS_LOG_FUNCTION (this << *packet << src << dst);
539 
540  Ipv6Header ipHeader;
541  SixLowPanHc1 hc1Header;
542  uint32_t size = 0;
543 
544  if ( packet->PeekHeader (ipHeader) != 0 )
545  {
546  packet->RemoveHeader (ipHeader);
547  size += ipHeader.GetSerializedSize ();
548 
549  hc1Header.SetHopLimit (ipHeader.GetHopLimit ());
550 
551  uint8_t bufOne[16];
552  uint8_t bufTwo[16];
553  Ipv6Address srcAddr = ipHeader.GetSourceAddress ();
554  srcAddr.GetBytes (bufOne);
555  Ipv6Address mySrcAddr = MakeLinkLocalAddressFromMac (src);
556 
557  NS_LOG_LOGIC ("Checking source compression: " << mySrcAddr << " - " << srcAddr );
558 
559  mySrcAddr.GetBytes (bufTwo);
560  bool isSrcSrc = (memcmp (bufOne + 8, bufTwo + 8, 8) == 0);
561 
562  if (srcAddr.IsLinkLocal () && isSrcSrc )
563  {
565  }
566  else if (srcAddr.IsLinkLocal () )
567  {
569  hc1Header.SetSrcInterface (bufOne + 8);
570  }
571  else if ( isSrcSrc )
572  {
574  hc1Header.SetSrcPrefix (bufOne);
575  }
576  else
577  {
579  hc1Header.SetSrcInterface (bufOne + 8);
580  hc1Header.SetSrcPrefix (bufOne);
581  }
582 
583  Ipv6Address dstAddr = ipHeader.GetDestinationAddress ();
584  dstAddr.GetBytes (bufOne);
585  Ipv6Address myDstAddr = MakeLinkLocalAddressFromMac (dst);
586 
587  NS_LOG_LOGIC ("Checking destination compression: " << myDstAddr << " - " << dstAddr );
588 
589  myDstAddr.GetBytes (bufTwo);
590  bool isDstDst = (memcmp (bufOne + 8, bufTwo + 8, 8) == 0);
591 
592  if (dstAddr.IsLinkLocal () && isDstDst )
593  {
595  }
596  else if (dstAddr.IsLinkLocal () )
597  {
599  hc1Header.SetDstInterface (bufOne + 8);
600  }
601  else if ( isDstDst )
602  {
604  hc1Header.SetDstPrefix (bufOne);
605  }
606  else
607  {
609  hc1Header.SetDstInterface (bufOne + 8);
610  hc1Header.SetDstPrefix (bufOne);
611  }
612 
613  if ( (ipHeader.GetFlowLabel () == 0) && (ipHeader.GetTrafficClass () == 0) )
614  {
615  hc1Header.SetTcflCompression (true);
616  }
617  else
618  {
619  hc1Header.SetTcflCompression (false);
620  hc1Header.SetTrafficClass (ipHeader.GetTrafficClass ());
621  hc1Header.SetFlowLabel (ipHeader.GetFlowLabel ());
622  }
623 
624  uint8_t nextHeader = ipHeader.GetNextHeader ();
625  hc1Header.SetNextHeader (nextHeader);
626 
627  // \todo implement HC2 compression
628  hc1Header.SetHc2HeaderPresent (false);
629 
630  NS_LOG_DEBUG ("HC1 Compression - HC1 header size = " << hc1Header.GetSerializedSize () );
631  NS_LOG_DEBUG ("HC1 Compression - packet size = " << packet->GetSize () );
632 
633  packet->AddHeader (hc1Header);
634 
635  return size;
636  }
637 
638  return 0;
639 }
640 
641 void
643 {
644  NS_LOG_FUNCTION (this << *packet << src << dst);
645 
646  Ipv6Header ipHeader;
647  SixLowPanHc1 encoding;
648 
649  uint32_t ret = packet->RemoveHeader (encoding);
650  NS_LOG_DEBUG ("removed " << ret << " bytes - pkt is " << *packet);
651  NS_UNUSED (ret);
652 
653  ipHeader.SetHopLimit (encoding.GetHopLimit ());
654 
655  switch (encoding.GetSrcCompression ())
656  {
657  const uint8_t* interface;
658  const uint8_t* prefix;
659  uint8_t address[16];
660 
662  prefix = encoding.GetSrcPrefix ();
663  interface = encoding.GetSrcInterface ();
664  for (int j = 0; j < 8; j++)
665  {
666  address[j + 8] = interface[j];
667  address[j] = prefix[j];
668  }
669  ipHeader.SetSourceAddress ( Ipv6Address (address) );
670  break;
672  prefix = encoding.GetSrcPrefix ();
673  for (int j = 0; j < 8; j++)
674  {
675  address[j + 8] = 0;
676  address[j] = prefix[j];
677  }
678  ipHeader.SetSourceAddress ( MakeGlobalAddressFromMac (src, Ipv6Address (address)));
679  break;
681  interface = encoding.GetSrcInterface ();
682  address[0] = 0xfe;
683  address[1] = 0x80;
684  for (int j = 0; j < 8; j++)
685  {
686  address[j + 8] = interface[j];
687  }
688  ipHeader.SetSourceAddress ( Ipv6Address (address) );
689  break;
692  break;
693  }
694 
695  switch (encoding.GetDstCompression ())
696  {
697  const uint8_t* interface;
698  const uint8_t* prefix;
699  uint8_t address[16];
700 
702  prefix = encoding.GetDstPrefix ();
703  interface = encoding.GetDstInterface ();
704  for (int j = 0; j < 8; j++)
705  {
706  address[j + 8] = interface[j];
707  address[j] = prefix[j];
708  }
709  ipHeader.SetDestinationAddress ( Ipv6Address (address) );
710  break;
712  prefix = encoding.GetDstPrefix ();
713  for (int j = 0; j < 8; j++)
714  {
715  address[j + 8] = 0;
716  address[j] = prefix[j];
717  }
718  ipHeader.SetDestinationAddress ( MakeGlobalAddressFromMac (dst, Ipv6Address (address)));
719  break;
721  interface = encoding.GetDstInterface ();
722  address[0] = 0xfe;
723  address[1] = 0x80;
724  for (int j = 0; j < 8; j++)
725  {
726  address[j + 8] = interface[j];
727  }
728  ipHeader.SetDestinationAddress ( Ipv6Address (address) );
729  break;
732  break;
733  }
734 
735  if ( !encoding.IsTcflCompression () )
736  {
737  ipHeader.SetFlowLabel (encoding.GetFlowLabel ());
738  ipHeader.SetTrafficClass (encoding.GetTrafficClass ());
739  }
740  else
741  {
742  ipHeader.SetFlowLabel (0);
743  ipHeader.SetTrafficClass (0);
744  }
745 
746  ipHeader.SetNextHeader (encoding.GetNextHeader ());
747 
748  ipHeader.SetPayloadLength (packet->GetSize ());
749 
750  NS_ASSERT_MSG (encoding.IsHc2HeaderPresent () == false,
751  "6LoWPAN: error in decompressing HC1 encoding, unsupported L4 compressed header present.");
752 
753  packet->AddHeader (ipHeader);
754 
755  NS_LOG_DEBUG ( "Rebuilt packet: " << *packet << " Size " << packet->GetSize () );
756 }
757 
758 uint32_t
760 {
761  NS_LOG_FUNCTION (this << *packet << src << dst);
762 
763  Ipv6Header ipHeader;
764  SixLowPanIphc iphcHeader;
765  uint32_t size = 0;
766 
767 
768  if ( packet->PeekHeader (ipHeader) != 0 )
769  {
770  packet->RemoveHeader (ipHeader);
771  size += ipHeader.GetSerializedSize ();
772 
773  // Set the TF field
774  if ( (ipHeader.GetFlowLabel () == 0) && (ipHeader.GetTrafficClass () == 0) )
775  {
776  iphcHeader.SetTf (SixLowPanIphc::TF_ELIDED);
777  }
778  else if ( (ipHeader.GetFlowLabel () != 0) && (ipHeader.GetTrafficClass () != 0) )
779  {
780  iphcHeader.SetTf (SixLowPanIphc::TF_FULL);
781  iphcHeader.SetEcn ( (ipHeader.GetTrafficClass () & 0xC0) >> 6);
782  iphcHeader.SetDscp ( ipHeader.GetTrafficClass () & 0x3F );
783  iphcHeader.SetFlowLabel (ipHeader.GetFlowLabel ());
784  }
785  else if ( (ipHeader.GetFlowLabel () == 0) && (ipHeader.GetTrafficClass () != 0) )
786  {
787  iphcHeader.SetTf (SixLowPanIphc::TF_FL_ELIDED);
788  iphcHeader.SetEcn ( (ipHeader.GetTrafficClass () & 0xC0) >> 6);
789  iphcHeader.SetDscp ( ipHeader.GetTrafficClass () & 0x3F );
790  }
791  else
792  {
794  iphcHeader.SetEcn ( (ipHeader.GetTrafficClass () & 0xC0) >> 6);
795  iphcHeader.SetFlowLabel (ipHeader.GetFlowLabel ());
796  }
797 
798  // Set the NH field and NextHeader
799 
800  uint8_t nextHeader = ipHeader.GetNextHeader ();
801  if (CanCompressLowPanNhc (nextHeader))
802  {
803  if (nextHeader == Ipv6Header::IPV6_UDP)
804  {
805  iphcHeader.SetNh (true);
806  size += CompressLowPanUdpNhc (packet, m_omitUdpChecksum);
807  }
808  else if (nextHeader == Ipv6Header::IPV6_IPV6)
809  {
810  iphcHeader.SetNh (true);
811  size += CompressLowPanIphc (packet, src, dst);
812  }
813  else
814  {
815  uint32_t sizeNhc = CompressLowPanNhc (packet, nextHeader, src, dst);
816  // the compression might fail due to Extension header size.
817  if (sizeNhc)
818  {
819  iphcHeader.SetNh (true);
820  size += sizeNhc;
821  }
822  else
823  {
824  iphcHeader.SetNh (false);
825  iphcHeader.SetNextHeader (nextHeader);
826  }
827  }
828  }
829  else
830  {
831  iphcHeader.SetNh (false);
832  iphcHeader.SetNextHeader (nextHeader);
833  }
834 
835 
836  // Set the HLIM field
837  if (ipHeader.GetHopLimit () == 1)
838  {
840  }
841  else if (ipHeader.GetHopLimit () == 0x40)
842  {
844  }
845  else if (ipHeader.GetHopLimit () == 0xFF)
846  {
848  }
849  else
850  {
851  iphcHeader.SetHlim (SixLowPanIphc::HLIM_INLINE);
852  // Set the HopLimit
853  iphcHeader.SetHopLimit (ipHeader.GetHopLimit ());
854  }
855 
856  // \todo Add the check of CID if there is context-based compression
857  // Set the CID field
858  iphcHeader.SetCid (false);
859 
860  // \todo Add the check of SAC if there is context-based compression
861  // Set the SAC field
862  iphcHeader.SetSac (false);
863 
864  uint8_t addressBuf[16];
865  uint8_t unicastAddrCheckerBuf[16];
866  Ipv6Address srcAddr = ipHeader.GetSourceAddress ();
867  srcAddr.GetBytes (addressBuf);
868 
869  Ipv6Address checker = Ipv6Address ("fe80:0000:0000:0000:0000:00ff:fe00:1");
870  checker.GetBytes (unicastAddrCheckerBuf);
871 
872  // \todo Add the check of SAC if there is context-based compression
873  // Set the Source Address
874  iphcHeader.SetSrcAddress (srcAddr);
875 
876  Ipv6Address mySrcAddr = MakeLinkLocalAddressFromMac (src);
877  NS_LOG_LOGIC ("Checking source compression: " << mySrcAddr << " - " << srcAddr );
878 
879  if ( mySrcAddr == srcAddr )
880  {
881  iphcHeader.SetSam (SixLowPanIphc::HC_COMPR_0);
882  }
883  else if (memcmp (addressBuf, unicastAddrCheckerBuf, 14) == 0)
884  {
885  iphcHeader.SetSam (SixLowPanIphc::HC_COMPR_16);
886  }
887  else if ( srcAddr.IsLinkLocal () )
888  {
889  iphcHeader.SetSam (SixLowPanIphc::HC_COMPR_64);
890  }
891  else
892  {
893  iphcHeader.SetSam (SixLowPanIphc::HC_INLINE);
894  }
895 
896  // Set the M field
897  if (ipHeader.GetDestinationAddress ().IsMulticast ())
898  {
899  iphcHeader.SetM (true);
900  }
901  else
902  {
903  iphcHeader.SetM (false);
904  }
905 
906  // \todo Add the check of DAC if there is context-based compression
907  // Set the DAC field
908  iphcHeader.SetDac (false);
909 
910  Ipv6Address dstAddr = ipHeader.GetDestinationAddress ();
911  dstAddr.GetBytes (addressBuf);
912 
913  // \todo Add the check of DAC if there is context-based compression
914  // Set the Destination Address
915  iphcHeader.SetDstAddress (dstAddr);
916 
917  Ipv6Address myDstAddr = MakeLinkLocalAddressFromMac (dst);
918  NS_LOG_LOGIC ("Checking destination compression: " << myDstAddr << " - " << dstAddr );
919 
920  if ( !iphcHeader.GetM () )
921  // Unicast address
922  {
923  if ( myDstAddr == dstAddr )
924  {
925  iphcHeader.SetDam (SixLowPanIphc::HC_COMPR_0);
926  }
927  else if (memcmp (addressBuf, unicastAddrCheckerBuf, 14) == 0)
928  {
929  iphcHeader.SetDam (SixLowPanIphc::HC_COMPR_16);
930  }
931  else if ( dstAddr.IsLinkLocal () )
932  {
933  iphcHeader.SetDam (SixLowPanIphc::HC_COMPR_64);
934  }
935  else
936  {
937  iphcHeader.SetDam (SixLowPanIphc::HC_INLINE);
938  }
939  }
940  else
941  {
942  // Multicast address
943  uint8_t multicastAddrCheckerBuf[16];
944  Ipv6Address multicastCheckAddress = Ipv6Address ("ff02::1");
945  multicastCheckAddress.GetBytes (multicastAddrCheckerBuf);
946 
947  // The address takes the form ff02::00XX.
948  if ( memcmp (addressBuf, multicastAddrCheckerBuf, 15) == 0 )
949  {
950  iphcHeader.SetDam (SixLowPanIphc::HC_COMPR_0);
951  }
952  // The address takes the form ffXX::00XX:XXXX.
953  // ffXX:0000:0000:0000:0000:0000:00XX:XXXX.
954  else if ( (addressBuf[0] == multicastAddrCheckerBuf[0])
955  && (memcmp (addressBuf + 2, multicastAddrCheckerBuf + 2, 11) == 0) )
956  {
957  iphcHeader.SetDam (SixLowPanIphc::HC_COMPR_16);
958  }
959  // The address takes the form ffXX::00XX:XXXX:XXXX.
960  // ffXX:0000:0000:0000:0000:00XX:XXXX:XXXX.
961  else if ( (addressBuf[0] == multicastAddrCheckerBuf[0])
962  && (memcmp (addressBuf + 2, multicastAddrCheckerBuf + 2, 9) == 0) )
963  {
964  iphcHeader.SetDam (SixLowPanIphc::HC_COMPR_64);
965  }
966  else
967  {
968  iphcHeader.SetDam (SixLowPanIphc::HC_INLINE);
969  }
970  }
971 
972  NS_LOG_DEBUG ("IPHC Compression - IPHC header size = " << iphcHeader.GetSerializedSize () );
973  NS_LOG_DEBUG ("IPHC Compression - packet size = " << packet->GetSize () );
974 
975  packet->AddHeader (iphcHeader);
976 
977  NS_LOG_DEBUG ("Packet after IPHC compression: " << *packet);
978 
979  return size;
980  }
981 
982  return 0;
983 }
984 
985 bool
987 {
988  bool ret = false;
989 
990  switch (nextHeader)
991  {
997  ret = true;
998  break;
1000  default:
1001  ret = false;
1002  }
1003  return ret;
1004 }
1005 
1006 void
1008 {
1009  NS_LOG_FUNCTION (this << *packet << src << dst);
1010 
1011  Ipv6Header ipHeader;
1012  SixLowPanIphc encoding;
1013 
1014  uint32_t ret = packet->RemoveHeader (encoding);
1015  NS_LOG_DEBUG ("removed " << ret << " bytes - pkt is " << *packet);
1016  NS_UNUSED (ret);
1017 
1018  // Hop Limit
1019  ipHeader.SetHopLimit (encoding.GetHopLimit ());
1020 
1021  // Source address
1022  if ( encoding.GetSac () )
1023  {
1024  if ( encoding.GetSam () == SixLowPanIphc::HC_INLINE )
1025  {
1026  ipHeader.SetSourceAddress ( Ipv6Address::GetAny () );
1027  }
1028  else
1029  {
1030  NS_ABORT_MSG ("SAC option not yet implemented");
1031  }
1032  }
1033  else
1034  {
1035  if ( encoding.GetSam () == SixLowPanIphc::HC_COMPR_0 )
1036  {
1038  }
1039  else
1040  {
1041  ipHeader.SetSourceAddress ( encoding.GetSrcAddress () );
1042  }
1043  }
1044  // Destination address
1045  if ( encoding.GetDac () )
1046  {
1047  if ((encoding.GetDam () == SixLowPanIphc::HC_INLINE && !encoding.GetM ())
1048  || (encoding.GetDam () == SixLowPanIphc::HC_COMPR_64 && encoding.GetM ())
1049  || (encoding.GetDam () == SixLowPanIphc::HC_COMPR_16 && encoding.GetM ())
1050  || (encoding.GetDam () == SixLowPanIphc::HC_COMPR_0 && encoding.GetM ()) )
1051  {
1052  NS_ABORT_MSG ("Reserved code found");
1053  }
1054  else
1055  {
1056  NS_ABORT_MSG ("DAC option not yet implemented");
1057  }
1058  }
1059  else
1060  {
1061  if ( !encoding.GetM () && encoding.GetDam () == SixLowPanIphc::HC_COMPR_0 )
1062  {
1064  }
1065  else
1066  {
1067  ipHeader.SetDestinationAddress ( encoding.GetDstAddress () );
1068  }
1069  }
1070 
1071  // Traffic class and Flow Label
1072  uint8_t traf = 0x00;
1073  switch (encoding.GetTf ())
1074  {
1076  traf |= encoding.GetEcn ();
1077  traf = ( traf << 6 ) | encoding.GetDscp ();
1078  ipHeader.SetTrafficClass (traf);
1079  ipHeader.SetFlowLabel ( encoding.GetFlowLabel () & 0xfff ); //Add 4-bit pad
1080  break;
1082  traf |= encoding.GetEcn ();
1083  traf <<= 2; // Add 2-bit pad
1084  ipHeader.SetTrafficClass (traf);
1085  ipHeader.SetFlowLabel (encoding.GetFlowLabel ());
1086  break;
1088  traf |= encoding.GetEcn ();
1089  traf = ( traf << 6 ) | encoding.GetDscp ();
1090  ipHeader.SetTrafficClass (traf);
1091  ipHeader.SetFlowLabel (0);
1092  break;
1094  ipHeader.SetFlowLabel (0);
1095  ipHeader.SetTrafficClass (0);
1096  break;
1097  }
1098 
1099  if ( encoding.GetNh () )
1100  {
1101  // Next Header
1102  uint8_t dispatchRawVal = 0;
1104 
1105  packet->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
1106  dispatchVal = SixLowPanDispatch::GetNhcDispatchType (dispatchRawVal);
1107 
1108  if (dispatchVal == SixLowPanDispatch::LOWPAN_UDPNHC)
1109  {
1111  DecompressLowPanUdpNhc (packet, ipHeader.GetSourceAddress (), ipHeader.GetDestinationAddress ());
1112  }
1113  else
1114  {
1115  ipHeader.SetNextHeader (DecompressLowPanNhc (packet, src, dst, ipHeader.GetSourceAddress (), ipHeader.GetDestinationAddress ()));
1116  }
1117  }
1118  else
1119  {
1120  ipHeader.SetNextHeader (encoding.GetNextHeader ());
1121  }
1122 
1123  ipHeader.SetPayloadLength (packet->GetSize ());
1124 
1125  packet->AddHeader (ipHeader);
1126 
1127  NS_LOG_DEBUG ( "Rebuilt packet: " << *packet << " Size " << packet->GetSize () );
1128 
1129 }
1130 
1131 uint32_t
1132 SixLowPanNetDevice::CompressLowPanNhc (Ptr<Packet> packet, uint8_t headerType, Address const &src, Address const &dst)
1133 {
1134  NS_LOG_FUNCTION (this << *packet << int(headerType));
1135 
1136  SixLowPanNhcExtension nhcHeader;
1137  uint32_t size = 0;
1138  Buffer blob;
1139 
1140  if (headerType == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1141  {
1142  Ipv6ExtensionHopByHopHeader hopHeader;
1143  packet->PeekHeader (hopHeader);
1144  if (hopHeader.GetLength () >= 0xff)
1145  {
1146  NS_LOG_DEBUG ("LOWPAN_NHC MUST NOT be used to encode IPv6 Extension Headers "
1147  "that have more than 255 octets following the Length field after compression. "
1148  "Packet uncompressed.");
1149  return 0;
1150  }
1151 
1152  size += packet->RemoveHeader (hopHeader);
1154 
1155  // recursively compress other headers
1156  uint8_t nextHeader = hopHeader.GetNextHeader ();
1157  if (CanCompressLowPanNhc (nextHeader))
1158  {
1159  if (nextHeader == Ipv6Header::IPV6_UDP)
1160  {
1161  nhcHeader.SetNh (true);
1162  size += CompressLowPanUdpNhc (packet, m_omitUdpChecksum);
1163  }
1164  else if (nextHeader == Ipv6Header::IPV6_IPV6)
1165  {
1166  nhcHeader.SetNh (true);
1167  size += CompressLowPanIphc (packet, src, dst);
1168  }
1169  else
1170  {
1171  uint32_t sizeNhc = CompressLowPanNhc (packet, nextHeader, src, dst);
1172  // the compression might fail due to Extension header size.
1173  if (sizeNhc)
1174  {
1175  nhcHeader.SetNh (true);
1176  size += sizeNhc;
1177  }
1178  else
1179  {
1180  nhcHeader.SetNh (false);
1181  nhcHeader.SetNextHeader (nextHeader);
1182  }
1183  }
1184  }
1185  else
1186  {
1187  nhcHeader.SetNh (false);
1188  nhcHeader.SetNextHeader (nextHeader);
1189  }
1190 
1191  uint32_t blobSize = hopHeader.GetSerializedSize ();
1192  blob.AddAtStart (blobSize);
1193  hopHeader.Serialize (blob.Begin ());
1194  blob.RemoveAtStart (2);
1195  blobSize = blob.GetSize ();
1196  nhcHeader.SetBlob (blob.PeekData (), blobSize);
1197  }
1198  else if (headerType == Ipv6Header::IPV6_EXT_ROUTING)
1199  {
1200  Ipv6ExtensionRoutingHeader routingHeader;
1201  packet->PeekHeader (routingHeader);
1202  if (routingHeader.GetLength () >= 0xff)
1203  {
1204  NS_LOG_DEBUG ("LOWPAN_NHC MUST NOT be used to encode IPv6 Extension Headers "
1205  "that have more than 255 octets following the Length field after compression. "
1206  "Packet uncompressed.");
1207  return 0;
1208  }
1209 
1210  size += packet->RemoveHeader (routingHeader);
1212 
1213  // recursively compress other headers
1214  uint8_t nextHeader = routingHeader.GetNextHeader ();
1215  if (CanCompressLowPanNhc (nextHeader))
1216  {
1217  if (nextHeader == Ipv6Header::IPV6_UDP)
1218  {
1219  nhcHeader.SetNh (true);
1220  size += CompressLowPanUdpNhc (packet, m_omitUdpChecksum);
1221  }
1222  else if (nextHeader == Ipv6Header::IPV6_IPV6)
1223  {
1224  nhcHeader.SetNh (true);
1225  size += CompressLowPanIphc (packet, src, dst);
1226  }
1227  else
1228  {
1229  uint32_t sizeNhc = CompressLowPanNhc (packet, nextHeader, src, dst);
1230  // the compression might fail due to Extension header size.
1231  if (sizeNhc)
1232  {
1233  nhcHeader.SetNh (true);
1234  size += sizeNhc;
1235  }
1236  else
1237  {
1238  nhcHeader.SetNh (false);
1239  nhcHeader.SetNextHeader (nextHeader);
1240  }
1241  }
1242  }
1243  else
1244  {
1245  nhcHeader.SetNh (false);
1246  nhcHeader.SetNextHeader (nextHeader);
1247  }
1248 
1249  uint32_t blobSize = routingHeader.GetSerializedSize ();
1250  blob.AddAtStart (blobSize);
1251  routingHeader.Serialize (blob.Begin ());
1252  blob.RemoveAtStart (2);
1253  blobSize = blob.GetSize ();
1254  nhcHeader.SetBlob (blob.PeekData (), blobSize);
1255  }
1256  else if (headerType == Ipv6Header::IPV6_EXT_FRAGMENTATION)
1257  {
1258  Ipv6ExtensionFragmentHeader fragHeader;
1259  packet->PeekHeader (fragHeader);
1260  if (fragHeader.GetLength () >= 0xff)
1261  {
1262  NS_LOG_DEBUG ("LOWPAN_NHC MUST NOT be used to encode IPv6 Extension Headers "
1263  "that have more than 255 octets following the Length field after compression. "
1264  "Packet uncompressed.");
1265  return 0;
1266  }
1267  size += packet->RemoveHeader (fragHeader);
1269 
1270  // recursively compress other headers
1271  uint8_t nextHeader = fragHeader.GetNextHeader ();
1272  if (CanCompressLowPanNhc (nextHeader))
1273  {
1274  if (nextHeader == Ipv6Header::IPV6_UDP)
1275  {
1276  nhcHeader.SetNh (true);
1277  size += CompressLowPanUdpNhc (packet, m_omitUdpChecksum);
1278  }
1279  else if (nextHeader == Ipv6Header::IPV6_IPV6)
1280  {
1281  nhcHeader.SetNh (true);
1282  size += CompressLowPanIphc (packet, src, dst);
1283  }
1284  else
1285  {
1286  uint32_t sizeNhc = CompressLowPanNhc (packet, nextHeader, src, dst);
1287  // the compression might fail due to Extension header size.
1288  if (sizeNhc)
1289  {
1290  nhcHeader.SetNh (true);
1291  size += sizeNhc;
1292  }
1293  else
1294  {
1295  nhcHeader.SetNh (false);
1296  nhcHeader.SetNextHeader (nextHeader);
1297  }
1298  }
1299  }
1300  else
1301  {
1302  nhcHeader.SetNh (false);
1303  nhcHeader.SetNextHeader (nextHeader);
1304  }
1305 
1306  uint32_t blobSize = fragHeader.GetSerializedSize ();
1307  blob.AddAtStart (blobSize);
1308  fragHeader.Serialize (blob.Begin ());
1309  blob.RemoveAtStart (2);
1310  blobSize = blob.GetSize ();
1311  nhcHeader.SetBlob (blob.PeekData (), blobSize);
1312  }
1313  else if (headerType == Ipv6Header::IPV6_EXT_DESTINATION)
1314  {
1315  Ipv6ExtensionDestinationHeader destHeader;
1316  packet->PeekHeader (destHeader);
1317  if (destHeader.GetLength () >= 0xff)
1318  {
1319  NS_LOG_DEBUG ("LOWPAN_NHC MUST NOT be used to encode IPv6 Extension Headers "
1320  "that have more than 255 octets following the Length field after compression. "
1321  "Packet uncompressed.");
1322  return 0;
1323  }
1324  size += packet->RemoveHeader (destHeader);
1326 
1327  // recursively compress other headers
1328  uint8_t nextHeader = destHeader.GetNextHeader ();
1329  if (CanCompressLowPanNhc (nextHeader))
1330  {
1331  if (nextHeader == Ipv6Header::IPV6_UDP)
1332  {
1333  nhcHeader.SetNh (true);
1334  size += CompressLowPanUdpNhc (packet, m_omitUdpChecksum);
1335  }
1336  else if (nextHeader == Ipv6Header::IPV6_IPV6)
1337  {
1338  nhcHeader.SetNh (true);
1339  size += CompressLowPanIphc (packet, src, dst);
1340  }
1341  else
1342  {
1343  uint32_t sizeNhc = CompressLowPanNhc (packet, nextHeader, src, dst);
1344  // the compression might fail due to Extension header size.
1345  if (sizeNhc)
1346  {
1347  nhcHeader.SetNh (true);
1348  size += sizeNhc;
1349  }
1350  else
1351  {
1352  nhcHeader.SetNh (false);
1353  nhcHeader.SetNextHeader (nextHeader);
1354  }
1355  }
1356  }
1357  else
1358  {
1359  nhcHeader.SetNh (false);
1360  nhcHeader.SetNextHeader (nextHeader);
1361  }
1362 
1363  uint32_t blobSize = destHeader.GetSerializedSize ();
1364  blob.AddAtStart (blobSize);
1365  destHeader.Serialize (blob.Begin ());
1366  blob.RemoveAtStart (2);
1367  blobSize = blob.GetSize ();
1368  nhcHeader.SetBlob (blob.PeekData (), blobSize);
1369  }
1370  else if (headerType == Ipv6Header::IPV6_EXT_MOBILITY)
1371  {
1372  // \todo: IPv6 Mobility Header is not supported in ns-3
1373  NS_ABORT_MSG ("IPv6 Mobility Header is not supported in ns-3 yet");
1374  return 0;
1375  }
1376  else
1377  {
1378  NS_ABORT_MSG ("Unexpected Extension Header");
1379  }
1380 
1381  NS_LOG_DEBUG ("NHC Compression - NHC header size = " << nhcHeader.GetSerializedSize () );
1382  NS_LOG_DEBUG ("NHC Compression - packet size = " << packet->GetSize () );
1383 
1384  packet->AddHeader (nhcHeader);
1385 
1386  NS_LOG_DEBUG ("Packet after NHC compression: " << *packet);
1387  return size;
1388 }
1389 
1390 uint8_t
1391 SixLowPanNetDevice::DecompressLowPanNhc (Ptr<Packet> packet, Address const &src, Address const &dst, Ipv6Address srcAddress, Ipv6Address dstAddress)
1392 {
1393  NS_LOG_FUNCTION (this << *packet);
1394 
1395  SixLowPanNhcExtension encoding;
1396 
1397  uint32_t ret = packet->RemoveHeader (encoding);
1398  NS_LOG_DEBUG ("removed " << ret << " bytes - pkt is " << *packet);
1399  NS_UNUSED (ret);
1400 
1401  Ipv6ExtensionHopByHopHeader hopHeader;
1402  Ipv6ExtensionRoutingHeader routingHeader;
1403  Ipv6ExtensionFragmentHeader fragHeader;
1404  Ipv6ExtensionDestinationHeader destHeader;
1405 
1406  uint32_t blobSize;
1407  uint8_t blobData[260];
1408  blobSize = encoding.CopyBlob (blobData + 2, 260);
1409  uint8_t paddingSize = 0;
1410 
1411  uint8_t actualEncodedHeaderType = encoding.GetEid ();
1412  uint8_t actualHeaderType;
1413  Buffer blob;
1414 
1415  switch (actualEncodedHeaderType)
1416  {
1418  actualHeaderType = Ipv6Header::IPV6_EXT_HOP_BY_HOP;
1419  if ( encoding.GetNh () )
1420  {
1421  // Next Header
1422  uint8_t dispatchRawVal = 0;
1424 
1425  packet->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
1426  dispatchVal = SixLowPanDispatch::GetNhcDispatchType (dispatchRawVal);
1427 
1428  if (dispatchVal == SixLowPanDispatch::LOWPAN_UDPNHC)
1429  {
1430  blobData [0] = Ipv6Header::IPV6_UDP;
1431  DecompressLowPanUdpNhc (packet, srcAddress, dstAddress);
1432  }
1433  else
1434  {
1435  blobData [0] = DecompressLowPanNhc (packet, src, dst, srcAddress, dstAddress);
1436  }
1437  }
1438  else
1439  {
1440  blobData [0] = encoding.GetNextHeader ();
1441  }
1442 
1443  // manually add some padding if needed
1444  if ((blobSize + 2) % 8 > 0)
1445  {
1446  paddingSize = 8 - (blobSize + 2) % 8;
1447  }
1448  if (paddingSize == 1)
1449  {
1450  blobData[blobSize + 2] = 0;
1451  }
1452  else if (paddingSize > 1)
1453  {
1454  blobData[blobSize + 2] = 1;
1455  blobData[blobSize + 2 + 1] = paddingSize - 2;
1456  for (uint8_t i = 0; i < paddingSize - 2; i++)
1457  {
1458  blobData[blobSize + 2 + 2 + i] = 0;
1459  }
1460  }
1461  blobData [1] = ((blobSize + 2 + paddingSize) >> 3) - 1;
1462  blob.AddAtStart (blobSize + 2 + paddingSize);
1463  blob.Begin ().Write (blobData, blobSize + 2 + paddingSize);
1464  hopHeader.Deserialize (blob.Begin ());
1465 
1466  packet->AddHeader (hopHeader);
1467  break;
1468 
1470  actualHeaderType = Ipv6Header::IPV6_EXT_ROUTING;
1471  if ( encoding.GetNh () )
1472  {
1473  // Next Header
1474  uint8_t dispatchRawVal = 0;
1476 
1477  packet->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
1478  dispatchVal = SixLowPanDispatch::GetNhcDispatchType (dispatchRawVal);
1479 
1480  if (dispatchVal == SixLowPanDispatch::LOWPAN_UDPNHC)
1481  {
1482  blobData [0] = Ipv6Header::IPV6_UDP;
1483  DecompressLowPanUdpNhc (packet, srcAddress, dstAddress);
1484  }
1485  else
1486  {
1487  blobData [0] = DecompressLowPanNhc (packet, src, dst, srcAddress, dstAddress);
1488  }
1489  }
1490  else
1491  {
1492  blobData [0] = encoding.GetNextHeader ();
1493  }
1494  blobData [1] = ((blobSize + 2) >> 3) - 1;
1495  blob.AddAtStart (blobSize + 2);
1496  blob.Begin ().Write (blobData, blobSize + 2);
1497  routingHeader.Deserialize (blob.Begin ());
1498  packet->AddHeader (routingHeader);
1499  break;
1500 
1502  actualHeaderType = Ipv6Header::IPV6_EXT_FRAGMENTATION;
1503  if ( encoding.GetNh () )
1504  {
1505  // Next Header
1506  uint8_t dispatchRawVal = 0;
1508 
1509  packet->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
1510  dispatchVal = SixLowPanDispatch::GetNhcDispatchType (dispatchRawVal);
1511 
1512  if (dispatchVal == SixLowPanDispatch::LOWPAN_UDPNHC)
1513  {
1514  blobData [0] = Ipv6Header::IPV6_UDP;
1515  DecompressLowPanUdpNhc (packet, srcAddress, dstAddress);
1516  }
1517  else
1518  {
1519  blobData [0] = DecompressLowPanNhc (packet, src, dst, srcAddress, dstAddress);
1520  }
1521  }
1522  else
1523  {
1524  blobData [0] = encoding.GetNextHeader ();
1525  }
1526  blobData [1] = 0;
1527  fragHeader.Deserialize (blob.Begin ());
1528  packet->AddHeader (fragHeader);
1529  break;
1530 
1532  actualHeaderType = Ipv6Header::IPV6_EXT_DESTINATION;
1533  if ( encoding.GetNh () )
1534  {
1535  // Next Header
1536  uint8_t dispatchRawVal = 0;
1538 
1539  packet->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
1540  dispatchVal = SixLowPanDispatch::GetNhcDispatchType (dispatchRawVal);
1541 
1542  if (dispatchVal == SixLowPanDispatch::LOWPAN_UDPNHC)
1543  {
1544  blobData [0] = Ipv6Header::IPV6_UDP;
1545  DecompressLowPanUdpNhc (packet, srcAddress, dstAddress);
1546  }
1547  else
1548  {
1549  blobData [0] = DecompressLowPanNhc (packet, src, dst, srcAddress, dstAddress);
1550  }
1551  }
1552  else
1553  {
1554  blobData [0] = encoding.GetNextHeader ();
1555  }
1556 
1557  // manually add some padding if needed
1558  if ((blobSize + 2) % 8 > 0)
1559  {
1560  paddingSize = 8 - (blobSize + 2) % 8;
1561  }
1562  if (paddingSize == 1)
1563  {
1564  blobData[blobSize + 2] = 0;
1565  }
1566  else if (paddingSize > 1)
1567  {
1568  blobData[blobSize + 2] = 1;
1569  blobData[blobSize + 2 + 1] = paddingSize - 2;
1570  for (uint8_t i = 0; i < paddingSize - 2; i++)
1571  {
1572  blobData[blobSize + 2 + 2 + i] = 0;
1573  }
1574  }
1575  blobData [1] = ((blobSize + 2 + paddingSize) >> 3) - 1;
1576  blob.AddAtStart (blobSize + 2 + paddingSize);
1577  blob.Begin ().Write (blobData, blobSize + 2 + paddingSize);
1578  destHeader.Deserialize (blob.Begin ());
1579 
1580  packet->AddHeader (destHeader);
1581  break;
1583  // \todo: IPv6 Mobility Header is not supported in ns-3
1584  NS_ABORT_MSG ("IPv6 Mobility Header is not supported in ns-3 yet");
1585  break;
1587  actualHeaderType = Ipv6Header::IPV6_IPV6;
1588  DecompressLowPanIphc (packet, src, dst);
1589  break;
1590  default:
1591  NS_ABORT_MSG ("Trying to decode unknown Extension Header");
1592  break;
1593  }
1594 
1595  NS_LOG_DEBUG ( "Rebuilt packet: " << *packet << " Size " << packet->GetSize () );
1596  return actualHeaderType;
1597 }
1598 
1599 uint32_t
1601 {
1602  NS_LOG_FUNCTION (this << *packet << int(omitChecksum));
1603 
1604  UdpHeader udpHeader;
1605  SixLowPanUdpNhcExtension udpNhcHeader;
1606  uint32_t size = 0;
1607 
1608  NS_ASSERT_MSG (packet->PeekHeader (udpHeader) != 0, "UDP header not found, abort");
1609 
1610  size += packet->RemoveHeader (udpHeader);
1611 
1612  // Set the C field and checksum
1613  udpNhcHeader.SetC (false);
1614  uint16_t checksum = udpHeader.GetChecksum ();
1615  udpNhcHeader.SetChecksum (checksum);
1616 
1617  if (omitChecksum && udpHeader.IsChecksumOk ())
1618  {
1619  udpNhcHeader.SetC (true);
1620  }
1621 
1622  // Set the value of the ports
1623  udpNhcHeader.SetSrcPort (udpHeader.GetSourcePort ());
1624  udpNhcHeader.SetDstPort (udpHeader.GetDestinationPort ());
1625 
1626  //Set the P field
1627  if ( (udpHeader.GetSourcePort () >> 4 ) == 0xf0b && (udpHeader.GetDestinationPort () >> 4 ) == 0xf0b )
1628  {
1630  }
1631  else if ( (udpHeader.GetSourcePort () >> 8 ) == 0xf0 && (udpHeader.GetDestinationPort () >> 8 ) != 0xf0 )
1632  {
1634  }
1635  else if ( (udpHeader.GetSourcePort () >> 8 ) != 0xf0 && (udpHeader.GetDestinationPort () >> 8 ) == 0xf0 )
1636  {
1638  }
1639  else
1640  {
1642  }
1643 
1644  NS_LOG_DEBUG ("UDP_NHC Compression - UDP_NHC header size = " << udpNhcHeader.GetSerializedSize () );
1645  NS_LOG_DEBUG ("UDP_NHC Compression - packet size = " << packet->GetSize () );
1646 
1647  packet->AddHeader (udpNhcHeader);
1648 
1649  NS_LOG_DEBUG ("Packet after UDP_NHC compression: " << *packet);
1650 
1651  return size;
1652 }
1653 
1654 void
1656 {
1657  NS_LOG_FUNCTION (this << *packet);
1658 
1659  UdpHeader udpHeader;
1660  SixLowPanUdpNhcExtension encoding;
1661 
1662  uint32_t ret = packet->RemoveHeader (encoding);
1663  NS_LOG_DEBUG ("removed " << ret << " bytes - pkt is " << *packet);
1664  NS_UNUSED (ret);
1665 
1666  // Set the value of the ports
1667  switch ( encoding.GetPorts () )
1668  {
1669  uint16_t temp;
1671  udpHeader.SetSourcePort (encoding.GetSrcPort ());
1672  udpHeader.SetDestinationPort (encoding.GetDstPort ());
1673  break;
1675  udpHeader.SetSourcePort (encoding.GetSrcPort ());
1676  temp = 0xf0;
1677  temp |= (temp << 8) | encoding.GetDstPort ();
1678  udpHeader.SetDestinationPort (temp);
1679  break;
1681  temp = 0xf0;
1682  temp |= (temp << 8) | encoding.GetSrcPort ();
1683  udpHeader.SetSourcePort (temp);
1684  udpHeader.SetDestinationPort (encoding.GetDstPort ());
1685  break;
1687  temp = 0xf0b;
1688  temp |= (temp << 4) | encoding.GetSrcPort ();
1689  udpHeader.SetSourcePort (temp);
1690  temp = 0xf0b;
1691  temp |= (temp << 4) | encoding.GetDstPort ();
1692  udpHeader.SetDestinationPort (temp);
1693  break;
1694  }
1695 
1696  // Get the C field and checksum
1697  if (Node::ChecksumEnabled ())
1698  {
1699  if ( encoding.GetC () )
1700  {
1701  NS_LOG_LOGIC ("Recalculating UDP Checksum");
1702  udpHeader.EnableChecksums ();
1703  udpHeader.InitializeChecksum (saddr,
1704  daddr,
1706  packet->AddHeader (udpHeader);
1707  }
1708  else
1709  {
1710  NS_LOG_LOGIC ("Forcing UDP Checksum to " << encoding.GetChecksum ());
1711  udpHeader.ForceChecksum (encoding.GetChecksum ());
1712  packet->AddHeader (udpHeader);
1713  NS_LOG_LOGIC ("UDP checksum is ok ? " << udpHeader.IsChecksumOk ());
1714  }
1715  }
1716  else
1717  {
1718  packet->AddHeader (udpHeader);
1719  }
1720 
1721  NS_LOG_DEBUG ( "Rebuilt packet: " << *packet << " Size " << packet->GetSize () );
1722 }
1723 
1725  uint32_t origPacketSize,
1726  uint32_t origHdrSize,
1727  std::list<Ptr<Packet> >& listFragments)
1728 {
1729  NS_LOG_FUNCTION (this << *packet);
1730 
1731  Ptr<Packet> p = packet->Copy ();
1732 
1733  uint16_t offsetData = 0;
1734  uint16_t offset = 0;
1735  uint16_t l2Mtu = m_netDevice->GetMtu ();
1736  uint32_t packetSize = packet->GetSize ();
1737  uint32_t compressedHeaderSize = packetSize - (origPacketSize - origHdrSize);
1738 
1739  uint16_t tag = uint16_t (m_rng->GetValue (0, 65535));
1740  NS_LOG_LOGIC ("random tag " << tag << " - test " << packetSize );
1741 
1742  // first fragment
1743  SixLowPanFrag1 frag1Hdr;
1744  frag1Hdr.SetDatagramTag (tag);
1745 
1746  uint32_t size;
1747  NS_ASSERT_MSG ( l2Mtu > frag1Hdr.GetSerializedSize (),
1748  "6LoWPAN: can not fragment, 6LoWPAN headers are bigger than MTU");
1749 
1750  size = l2Mtu - frag1Hdr.GetSerializedSize () - compressedHeaderSize;
1751  size -= size % 8;
1752  size += compressedHeaderSize;
1753 
1754  frag1Hdr.SetDatagramSize (origPacketSize);
1755 
1756  Ptr<Packet> fragment1 = p->CreateFragment (offsetData, size);
1757  offset += size + origHdrSize - compressedHeaderSize;
1758  offsetData += size;
1759 
1760  fragment1->AddHeader (frag1Hdr);
1761  listFragments.push_back (fragment1);
1762 
1763  bool moreFrag = true;
1764  do
1765  {
1766  SixLowPanFragN fragNHdr;
1767  fragNHdr.SetDatagramTag (tag);
1768  fragNHdr.SetDatagramSize (origPacketSize);
1769  fragNHdr.SetDatagramOffset ((offset) >> 3);
1770 
1771  size = l2Mtu - fragNHdr.GetSerializedSize ();
1772  size -= size % 8;
1773 
1774  if ( (offsetData + size) > packetSize )
1775  {
1776  size = packetSize - offsetData;
1777  moreFrag = false;
1778  }
1779 
1780  NS_LOG_LOGIC ("Fragment creation - " << offset << ", " << offset );
1781  Ptr<Packet> fragment = p->CreateFragment (offsetData, size);
1782  NS_LOG_LOGIC ("Fragment created - " << offset << ", " << fragment->GetSize () );
1783 
1784  offset += size;
1785  offsetData += size;
1786 
1787  fragment->AddHeader (fragNHdr);
1788  listFragments.push_back (fragment);
1789 
1790  }
1791  while (moreFrag);
1792 
1793  return;
1794 }
1795 
1796 bool SixLowPanNetDevice::ProcessFragment (Ptr<Packet>& packet, Address const &src, Address const &dst, bool isFirst)
1797 {
1798  NS_LOG_FUNCTION ( this << *packet );
1799  SixLowPanFrag1 frag1Header;
1800  SixLowPanFragN fragNHeader;
1801  FragmentKey key;
1802  uint16_t packetSize;
1803  key.first = std::pair<Address, Address> (src, dst);
1804 
1805  Ptr<Packet> p = packet->Copy ();
1806  uint16_t offset = 0;
1807 
1808  /* Implementation note:
1809  *
1810  * The fragment offset is relative to the *uncompressed* packet.
1811  * On the other hand, the packet can not be uncompressed correctly without all
1812  * its fragments, as the UDP checksum can not be computed otherwise.
1813  *
1814  * As a consequence we must uncompress the packet twice, and save its first
1815  * fragment for the final one.
1816  */
1817 
1818  if ( isFirst )
1819  {
1820  uint8_t dispatchRawValFrag1 = 0;
1821  SixLowPanDispatch::Dispatch_e dispatchValFrag1;
1822 
1823  p->RemoveHeader (frag1Header);
1824  packetSize = frag1Header.GetDatagramSize ();
1825  p->CopyData (&dispatchRawValFrag1, sizeof(dispatchRawValFrag1));
1826  dispatchValFrag1 = SixLowPanDispatch::GetDispatchType (dispatchRawValFrag1);
1827  NS_LOG_DEBUG ( "Dispatches: " << int(dispatchRawValFrag1) << " - " << int(dispatchValFrag1) );
1828  NS_LOG_DEBUG ( "Packet: " << *p );
1829 
1830  switch ( dispatchValFrag1 )
1831  {
1833  {
1834  SixLowPanIpv6 uncompressedHdr;
1835  p->RemoveHeader(uncompressedHdr);
1836  }
1837  break;
1839  DecompressLowPanHc1 (p, src, dst);
1840  break;
1842  DecompressLowPanIphc (p, src, dst);
1843  break;
1844  default:
1845  NS_FATAL_ERROR ("Unsupported 6LoWPAN encoding, exiting.");
1846  break;
1847  }
1848 
1849  key.second = std::pair<uint16_t, uint16_t> (frag1Header.GetDatagramSize (), frag1Header.GetDatagramTag ());
1850  }
1851  else
1852  {
1853  p->RemoveHeader (fragNHeader);
1854  packetSize = fragNHeader.GetDatagramSize ();
1855  offset = fragNHeader.GetDatagramOffset () << 3;
1856  key.second = std::pair<uint16_t, uint16_t> (fragNHeader.GetDatagramSize (), fragNHeader.GetDatagramTag ());
1857  }
1858 
1859  Ptr<Fragments> fragments;
1860 
1861  MapFragments_t::iterator it = m_fragments.find (key);
1862  if (it == m_fragments.end ())
1863  {
1864  // erase the oldest packet.
1866  {
1867  MapFragmentsTimers_t::iterator iter;
1868  MapFragmentsTimers_t::iterator iterFound = m_fragmentsTimers.begin ();
1869  for ( iter = m_fragmentsTimers.begin (); iter != m_fragmentsTimers.end (); iter++)
1870  {
1871  if ( iter->second.GetTs () < iterFound->second.GetTs () )
1872  {
1873  iterFound = iter;
1874  }
1875  }
1876  FragmentKey oldestKey = iterFound->first;
1877 
1878  std::list< Ptr<Packet> > storedFragments = m_fragments[oldestKey]->GetFraments ();
1879  for (std::list< Ptr<Packet> >::iterator fragIter = storedFragments.begin ();
1880  fragIter != storedFragments.end (); fragIter++)
1881  {
1883  }
1884 
1885  m_fragmentsTimers[oldestKey].Cancel ();
1886  m_fragmentsTimers.erase (oldestKey);
1887  m_fragments[oldestKey] = 0;
1888  m_fragments.erase (oldestKey);
1889 
1890  }
1891  fragments = Create<Fragments> ();
1892  fragments->SetPacketSize (packetSize);
1893  m_fragments.insert (std::make_pair (key, fragments));
1894  uint32_t ifIndex = GetIfIndex ();
1897  key, ifIndex);
1898  }
1899  else
1900  {
1901  fragments = it->second;
1902  }
1903 
1904  fragments->AddFragment (p, offset);
1905 
1906  // add the very first fragment so we can correctly decode the packet once is rebuilt.
1907  // this is needed because otherwise the UDP header length and checksum can not be calculated.
1908  if ( isFirst )
1909  {
1910  fragments->AddFirstFragment (packet);
1911  }
1912 
1913  if ( fragments->IsEntire () )
1914  {
1915  packet = fragments->GetPacket ();
1916  NS_LOG_LOGIC ("Reconstructed packet: " << *packet);
1917 
1918  SixLowPanFrag1 frag1Header;
1919  packet->RemoveHeader (frag1Header);
1920 
1921  NS_LOG_LOGIC ("Rebuilt packet. Size " << packet->GetSize () << " - " << *packet);
1922  fragments = 0;
1923  m_fragments.erase (key);
1924  if (m_fragmentsTimers[key].IsRunning ())
1925  {
1926  NS_LOG_LOGIC ("Stopping 6LoWPAN WaitFragmentsTimer at " << Simulator::Now ().GetSeconds () << " due to complete packet");
1927  m_fragmentsTimers[key].Cancel ();
1928  }
1929  m_fragmentsTimers.erase (key);
1930  return true;
1931  }
1932 
1933  return false;
1934 }
1935 
1937 {
1938  NS_LOG_FUNCTION (this);
1939  m_packetSize = 0;
1940 }
1941 
1943 {
1944  NS_LOG_FUNCTION (this);
1945 }
1946 
1947 void SixLowPanNetDevice::Fragments::AddFragment (Ptr<Packet> fragment, uint16_t fragmentOffset)
1948 {
1949  NS_LOG_FUNCTION (this << fragmentOffset << *fragment);
1950 
1951  std::list<std::pair<Ptr<Packet>, uint16_t> >::iterator it;
1952  bool duplicate = false;
1953 
1954  for (it = m_fragments.begin (); it != m_fragments.end (); it++)
1955  {
1956  if (it->second > fragmentOffset)
1957  {
1958  break;
1959  }
1960  if (it->second == fragmentOffset)
1961  {
1962  duplicate = true;
1963  NS_ASSERT_MSG (fragment->GetSize () == it->first->GetSize (), "Duplicate fragment size differs. Aborting.");
1964  break;
1965  }
1966  }
1967  if (!duplicate)
1968  {
1969  m_fragments.insert (it, std::make_pair (fragment, fragmentOffset));
1970  }
1971 }
1972 
1974 {
1975  NS_LOG_FUNCTION (this << *fragment);
1976 
1977  m_firstFragment = fragment;
1978 }
1979 
1981 {
1982  NS_LOG_FUNCTION (this);
1983 
1984  bool ret = m_fragments.size () > 0;
1985  uint16_t lastEndOffset = 0;
1986 
1987  if (ret)
1988  {
1989  for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
1990  {
1991  // overlapping fragments should not exist
1992  NS_LOG_LOGIC ("Checking overlaps " << lastEndOffset << " - " << it->second );
1993 
1994  if (lastEndOffset < it->second)
1995  {
1996  ret = false;
1997  break;
1998  }
1999  // fragments might overlap in strange ways
2000  uint16_t fragmentEnd = it->first->GetSize () + it->second;
2001  lastEndOffset = std::max ( lastEndOffset, fragmentEnd );
2002  }
2003  }
2004 
2005  if ( ret && (lastEndOffset == m_packetSize))
2006  {
2007  return true;
2008  }
2009  return false;
2010 }
2011 
2013 {
2014  NS_LOG_FUNCTION (this);
2015 
2016  std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin ();
2017 
2018  Ptr<Packet> p = Create<Packet> ();
2019  uint16_t lastEndOffset = 0;
2020 
2021  p->AddAtEnd (m_firstFragment);
2022  it = m_fragments.begin ();
2023  lastEndOffset = it->first->GetSize ();
2024 
2025  for ( it++; it != m_fragments.end (); it++)
2026  {
2027  if ( lastEndOffset > it->second )
2028  {
2029  NS_ABORT_MSG ("Overlapping fragments found, forbidden condition");
2030  }
2031  else
2032  {
2033  NS_LOG_LOGIC ("Adding: " << *(it->first) );
2034  p->AddAtEnd (it->first);
2035  }
2036  lastEndOffset += it->first->GetSize ();
2037  }
2038 
2039  return p;
2040 }
2041 
2043 {
2044  NS_LOG_FUNCTION (this << packetSize);
2045  m_packetSize = packetSize;
2046 }
2047 
2048 std::list< Ptr<Packet> > SixLowPanNetDevice::Fragments::GetFraments () const
2049 {
2050  std::list< Ptr<Packet> > fragments;
2051  std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator iter;
2052  for ( iter = m_fragments.begin (); iter != m_fragments.end (); iter ++)
2053  {
2054  fragments.push_back (iter->first);
2055  }
2056  return fragments;
2057 }
2058 
2060 {
2061  NS_LOG_FUNCTION (this);
2062 
2063  MapFragments_t::iterator it = m_fragments.find (key);
2064  std::list< Ptr<Packet> > storedFragments = it->second->GetFraments ();
2065  for (std::list< Ptr<Packet> >::iterator fragIter = storedFragments.begin ();
2066  fragIter != storedFragments.end (); fragIter++)
2067  {
2069  }
2070  // clear the buffers
2071  it->second = 0;
2072 
2073  m_fragments.erase (key);
2074  m_fragmentsTimers.erase (key);
2075 }
2076 
2078 {
2079  Ipv6Address ipv6Addr = Ipv6Address::GetAny ();
2080 
2082  {
2084  }
2085  else
2086  {
2087  if (Mac64Address::IsMatchingType (addr))
2088  {
2090  }
2091  else if (Mac16Address::IsMatchingType (addr))
2092  {
2094  }
2095  }
2096  if (ipv6Addr.IsAny ())
2097  {
2098  NS_ABORT_MSG ("Unknown address type");
2099  }
2100  return ipv6Addr;
2101 }
2102 
2104 {
2105  Ipv6Address ipv6Addr = Ipv6Address::GetAny ();
2106 
2108  {
2110  }
2111  else
2112  {
2113  if (Mac64Address::IsMatchingType (addr))
2114  {
2116  }
2117  else if (Mac16Address::IsMatchingType (addr))
2118  {
2120  }
2121  }
2122  if (ipv6Addr.IsAny ())
2123  {
2124  NS_ABORT_MSG ("Unknown address type");
2125  }
2126  return ipv6Addr;
2127 }
2128 
2129 }
2130 
2131 // namespace ns3
bool IsAny() const
If the IPv6 address is the "Any" address.
uint8_t GetTrafficClass(void) const
Get the "Traffic class" field.
Definition: ipv6-header.cc:51
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
void SetCid(bool cidField)
Set the CID (Context Identifier Extension) compression.
uint8_t GetNextHeader(void) const
Get the Next Header field.
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
Definition: ipv6-header.cc:143
void DecompressLowPanUdpNhc(Ptr< Packet > packet, Ipv6Address saddr, Ipv6Address daddr)
Decompress the headers according to NHC compression.
static bool IsMatchingType(const Address &address)
uint8_t GetNextHeader(void) const
Get the next header.
Definition: ipv6-header.cc:81
Ports_e GetPorts(void) const
Get the compressed Src and Dst Ports.
void SetPayloadLength(uint16_t len)
Set the "Payload length" field.
Definition: ipv6-header.cc:66
void SetTcflCompression(bool tcflCompression)
Set the Traffic Class and Flow Labels as compressed.
Introspection did not find any typical Config paths.
Definition: ipv6-header.h:33
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
uint8_t GetNextHeader() const
Get the Next Header value.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
void InitializeChecksum(Address source, Address destination, uint8_t protocol)
Definition: udp-header.cc:75
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
AttributeValue implementation for Boolean.
Definition: boolean.h:34
void SetHopLimit(uint8_t hopLimit)
Set the Hop Limit field.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
void SetDstCompression(LowPanHc1Addr_e dstCompression)
Set Destination Compression type.
NetDevice::PromiscReceiveCallback m_promiscRxCallback
The callback used to notify higher layers that a packet has been received in promiscuous mode...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
6LoWPAN IPv6 uncomprssed header - see RFC 4944
void RemoveAtStart(uint32_t start)
Definition: buffer.cc:456
void SetNextHeader(uint8_t nextHeader)
Set the Next Header field values.
virtual void SetIfIndex(const uint32_t index)
static Mac16Address ConvertFrom(const Address &address)
void SetPacketSize(uint32_t packetSize)
Set the packet-to-be-defragmented size.
void AddFirstFragment(Ptr< Packet > fragment)
Add the first packet fragment.
TracedCallback< Ptr< const Packet >, Ptr< SixLowPanNetDevice >, uint32_t > m_txTrace
Callback to trace TX (transmission) packets.
static bool IsMatchingType(const Address &address)
Introspection did not find any typical Config paths.
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:81
static Dispatch_e GetDispatchType(uint8_t dispatch)
Get the Dispatch type.
static bool ChecksumEnabled(void)
Definition: node.cc:268
LOWPAN_IPHC base Encoding - see RFC 6282.
automatically resized byte buffer
Definition: buffer.h:92
void SetDestinationPort(uint16_t port)
Definition: udp-header.cc:55
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:380
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
virtual bool IsMulticast(void) const
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1072
void SetPorts(Ports_e port)
Set the compressed Src and Dst Ports.
void SetSrcCompression(LowPanHc1Addr_e srcCompression)
Set Source Compression type.
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:272
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
uint16_t GetDatagramSize(void) const
Get the datagram size.
static TypeId GetTypeId(void)
Get the type ID.
static Ipv6Address MakeAutoconfiguredAddress(Mac16Address addr, Ipv6Address prefix)
Make the autoconfigured IPv6 address with Mac16Address.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
uint16_t GetDatagramSize(void) const
Get the datagram size.
virtual Ptr< Channel > GetChannel(void) const
void SetSourcePort(uint16_t port)
Definition: udp-header.cc:60
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:766
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
void SetNextHeader(uint8_t next)
Set the "Next header" field.
Definition: ipv6-header.cc:76
LOWPAN_NHC Extension Header Encoding - see RFC 6282.
std::pair< std::pair< Address, Address >, std::pair< uint16_t, uint16_t > > FragmentKey
Fragment identifier type: src/dst address src/dst port.
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:338
uint16_t m_fragmentReassemblyListSize
How many packets can be rebuilt at the same time.
#define NS_FATAL_ERROR(msg)
Fatal error handling.
Definition: fatal-error.h:100
void SetDatagramOffset(uint8_t datagramOffset)
Set the datagram offset.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
void SetSam(HeaderCompression_e samField)
Set the SAM (Source Address Mode) compression.
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:819
6LoWPAN FRAGN header - see RFC 4944
TrafficClassFlowLabel_e GetTf(void) const
Get the TF (Traffic Class, Flow Label) compression.
virtual Address GetMulticast(Ipv4Address multicastGroup) const
Make and return a MAC multicast address using the provided multicast group.
void SetDatagramSize(uint16_t datagramSize)
Set the datagram size.
bool IsChecksumOk(void) const
Is the UDP checksum correct ?
Definition: udp-header.cc:136
virtual bool SetMtu(const uint16_t mtu)
void SetNetDevice(Ptr< NetDevice > device)
Setup SixLowPan to be a proxy for the specified NetDevice.
bool IsTcflCompression() const
Check if the Traffic Class and Flow Labels are compressed.
bool GetM(void) const
Get the M (Multicast) compression.
void SetTrafficClass(uint8_t trafficClass)
Set the Traffic Class value.
Introspection did not find any typical Config paths.
a polymophic address class
Definition: address.h:90
uint16_t GetDstPort() const
Get the Destination Port.
bool GetNh(void) const
Get the Next Header field value.
std::map< FragmentKey, EventId >::iterator MapFragmentsTimersI_t
Container Iterator for fragment key -> exiration event.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:439
void ForceChecksum(uint16_t checksum)
Force the UDP checksum to a given value.
Definition: udp-header.cc:142
uint8_t GetDscp(void) const
Get the DSCP.
void SetHlim(Hlim_e hlimField)
Set the HLIM (Hop Limit) compression.
virtual uint32_t GetIfIndex(void) const
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
Definition: packet.cc:228
uint32_t CompressLowPanNhc(Ptr< Packet > packet, uint8_t headerType, Address const &src, Address const &dst)
Compress the headers according to NHC compression.
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
bool m_useIphc
Use IPHC or HC1.
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:317
Ptr< Node > m_node
Smart pointer to the Node.
uint16_t GetDatagramTag(void) const
Get the datagram tag.
Ipv6Address GetSrcAddress() const
Get the Source Address.
uint16_t GetSrcPort() const
Get the Destination Port.
void SetBlob(const uint8_t *blob, uint32_t size)
Set the option header data blob.
uint32_t CompressLowPanUdpNhc(Ptr< Packet > packet, bool omitChecksum)
Compress the headers according to NHC compression.
uint32_t CompressLowPanIphc(Ptr< Packet > packet, Address const &src, Address const &dst)
Compress the headers according to IPHC compression.
void SetHc2HeaderPresent(bool hc2HeaderPresent)
Set the next header a HC2 compressed header.
AttributeValue implementation for Time.
Definition: nstime.h:921
void SetDscp(uint8_t dscp)
Set the DSCP (6bits).
void EnableChecksums(void)
Enable checksum calculation for UDP.
Definition: udp-header.cc:49
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
uint8_t GetTrafficClass() const
Get the Traffic Class value.
Hold an unsigned integer type.
Definition: uinteger.h:44
void SetDstInterface(const uint8_t *dstInterface)
Set the destination interface.
uint32_t m_packetSize
The size of the reconstructed packet (bytes).
void SetSac(bool sacField)
Set the SAC (Source Address Compression) compression.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
bool IsHc2HeaderPresent() const
Check if there is a HC2 compressed header.
Ptr< NetDevice > GetNetDevice() const
Returns a smart pointer to the underlying NetDevice.
uint32_t GetFlowLabel(void) const
Get the "Flow label" field.
Definition: ipv6-header.cc:61
uint8_t const * PeekData(void) const
Definition: buffer.cc:733
void SetNh(bool nhField)
Set the NH (Next Header) compression.
Ipv6Address GetDstAddress() const
Get the Destination Address.
void SetChecksum(uint16_t checksum)
Set the Checksum field values.
uint16_t GetDatagramTag(void) const
Get the datagram tag.
uint8_t GetHopLimit(void) const
Get the Hop Limit field.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1290
LowPanHc1Addr_e GetDstCompression() const
Get Destination Compression type.
uint8_t GetEcn(void) const
Get the ECN.
void GetBytes(uint8_t buf[16]) const
Get the bytes corresponding to the address.
void SetDstPort(uint16_t port)
Set the Destination Port.
virtual bool IsLinkUp(void) const
void SetDatagramSize(uint16_t datagramSize)
Set the datagram size.
uint8_t GetHopLimit(void) const
Get the "Hop limit" field (TTL).
bool GetNh(void) const
Get the NH (Next Header) compression.
HeaderCompression_e GetDam(void) const
Get the DAM (Destination Address Mode) compression.
TracedCallback< DropReason, Ptr< const Packet >, Ptr< SixLowPanNetDevice >, uint32_t > m_dropTrace
Callback to trace drop packets.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
Buffer::Iterator Begin(void) const
Definition: buffer.h:1076
virtual void SetPromiscReceiveCallback(NetDevice::PromiscReceiveCallback cb)
#define list
void SetSrcPort(uint16_t port)
Set the Destination Port.
HeaderCompression_e GetSam(void) const
Get the SAM (Source Address Mode) compression.
static Mac48Address ConvertFrom(const Address &address)
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
uint16_t GetChecksum()
Return the checksum (only known after a Deserialize)
Definition: udp-header.cc:240
Time m_fragmentExpirationTimeout
Time limit for fragment rebuilding.
virtual bool NeedsArp(void) const
virtual bool IsBroadcast(void) const
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:122
bool m_forceEtherType
Force the EtherType number.
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:277
std::map< FragmentKey, Ptr< Fragments > >::iterator MapFragmentsI_t
Container Iterator for fragment key -> fragments.
uint8_t GetHopLimit(void) const
Get the "Hop limit" field (TTL).
Definition: ipv6-header.cc:91
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
virtual void SetNode(Ptr< Node > node)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SetNextHeader(uint8_t nextHeader)
Set the Next Header field.
std::list< Ptr< Packet > > GetFraments() const
Get a list of the current stored fragments.
uint32_t m_compressionThreshold
Minimum L2 payload size.
Shim performing 6LoWPAN compression, decompression and fragmentation.
uint32_t GetFlowLabel() const
Get the Flow Label value.
Ipv6Address MakeLinkLocalAddressFromMac(Address const &addr)
make a link-local address from a MAC address.
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
uint16_t GetSourcePort(void) const
Definition: udp-header.cc:65
bool IsEntire() const
If all fragments have been added.
bool GetC(void) const
Get the C (Checksum).
virtual Ptr< Node > GetNode(void) const
MapFragmentsTimers_t m_fragmentsTimers
Timers related to fragment rebuilding.
double GetValue(double min, double max)
Returns a random double from the uniform distribution with the specified range.
virtual Address GetBroadcast(void) const
Packet header for UDP packets.
Definition: udp-header.h:39
bool GetSac(void) const
Get the SAC (Source Address Compression) compression.
virtual void AddLinkChangeCallback(Callback< void > callback)
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
NetDevice::ReceiveCallback m_rxCallback
The callback used to notify higher layers that a packet has been received.
void SetSrcAddress(Ipv6Address srcAddress)
Set the Source Address.
bool GetDac(void) const
Get the DAC (Destination Address Compression) compression.
const uint8_t * GetDstPrefix() const
Get the destination prefix.
void DoFragmentation(Ptr< Packet > packet, uint32_t origPacketSize, uint32_t origHdrSize, std::list< Ptr< Packet > > &listFragments)
Return the instance type identifier.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:922
virtual uint32_t GetSerializedSize() const
Get the serialized size of the packet.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:223
uint32_t GetSize(void) const
Definition: buffer.h:1070
uint8_t GetNextHeader(void) const
Get the Next Header field value.
6LoWPAN HC1 header - see RFC 4944
virtual bool IsBridge(void) const
Return true if the net device is acting as a bridge.
Dispatch_e
Dispatch values, as defined in RFC4944 and RFC6282.
void SetHopLimit(uint8_t limit)
Set the "Hop limit" field (TTL).
Ptr< Packet > GetPacket() const
Get the entire packet.
void SetDac(bool dacField)
Set the DAC (Destination Address Compression) compression.
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:219
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:84
void SetSourceAddress(Ipv6Address src)
Set the "Source address" field.
Definition: ipv6-header.cc:96
void SetSrcInterface(const uint8_t *srcInterface)
Set the source interface.
uint16_t m_etherType
EtherType number (used only if m_forceEtherType is true)
uint8_t GetNextHeader() const
Get the next header.
void SetDstPrefix(const uint8_t *dstPrefix)
Set the destination prefix.
static Ipv6Address MakeAutoconfiguredLinkLocalAddress(Mac16Address mac)
Make the autoconfigured link-local IPv6 address with Mac16Address.
Describes an IPv6 address.
Definition: ipv6-address.h:47
void DecompressLowPanIphc(Ptr< Packet > packet, Address const &src, Address const &dst)
Decompress the headers according to IPHC compression.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
SixLowPanNetDevice()
Constructor for the SixLowPanNetDevice.
Ipv6Address MakeGlobalAddressFromMac(Address const &addr, Ipv6Address prefix)
make a global address from a MAC address.
void SetHopLimit(uint8_t limit)
Set the "Hop limit" field (TTL).
Definition: ipv6-header.cc:86
void SetFlowLabel(uint32_t flowLabel)
Set the Flow Label (20bits).
Eid_e GetEid(void) const
Get the Extension Header Type.
uint32_t GetId(void) const
Definition: node.cc:106
void ReceiveFromDevice(Ptr< NetDevice > device, Ptr< const Packet > packet, uint16_t protocol, Address const &source, Address const &destination, PacketType packetType)
receives all the packets from a NetDevice for further processing.
static Mac64Address ConvertFrom(const Address &address)
Network layer to device interface.
Definition: net-device.h:75
virtual bool SupportsSendFrom() const
const uint8_t * GetSrcPrefix() const
Get the source prefix.
virtual bool IsPointToPoint(void) const
Return true if the net device is on a point-to-point link.
Introspection did not find any typical Config paths.
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:101
virtual Address GetAddress(void) const
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:859
void SetFlowLabel(uint32_t flow)
Set the "Flow label" field.
Definition: ipv6-header.cc:56
uint32_t GetFlowLabel(void) const
Get the Flow Label.
static NhcDispatch_e GetNhcDispatchType(uint8_t dispatch)
Get the NhcDispatch type.
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
void SetEid(Eid_e extensionHeaderType)
Set the Extension Header Type.
Introspection did not find any typical Config paths.
bool CanCompressLowPanNhc(uint8_t headerType)
Checks if the next header can be compressed using NHC.
void Write(uint8_t const *buffer, uint32_t size)
Definition: buffer.cc:982
bool m_omitUdpChecksum
Omit UDP checksum in NC1 encoding.
bool DoSend(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber, bool doSendFrom)
void SetTrafficClass(uint8_t traffic)
Set the "Traffic class" field.
Definition: ipv6-header.cc:46
TracedCallback< Ptr< const Packet >, Ptr< SixLowPanNetDevice >, uint32_t > m_rxTrace
Callback to trace RX (reception) packets.
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:368
virtual uint16_t GetMtu(void) const
Returns the link-layer MTU for this interface.
void SetNh(bool nhField)
Set the NH field values.
void SetTf(TrafficClassFlowLabel_e tfField)
Set the TF (Traffic Class, Flow Label) compression.
#define NS_UNUSED(x)
Definition: unused.h:5
virtual bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
uint32_t CopyBlob(uint8_t *blob, uint32_t size) const
Get the option header data blob.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
static const uint32_t packetSize
void SetDstAddress(Ipv6Address dstAddress)
Set the Destination Address.
Ptr< NetDevice > m_netDevice
Smart pointer to the underlying NetDevice.
void HandleFragmentsTimeout(FragmentKey key, uint32_t iif)
Process the timeout for packet fragments.
bool AddAtStart(uint32_t start)
Definition: buffer.cc:309
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
void AddFragment(Ptr< Packet > fragment, uint16_t fragmentOffset)
Add a fragment to the pool.
tuple address
Definition: first.py:37
bool ProcessFragment(Ptr< Packet > &packet, Address const &src, Address const &dst, bool isFirst)
Process a packet fragment.
void SetM(bool mField)
Set the M (Multicast) compression.
NhcDispatch_e
Dispatch values for Next Header compression.
void SetSrcPrefix(const uint8_t *srcPrefix)
Set the source prefix.
uint16_t GetLength() const
Get the length of the extension.
static bool IsMatchingType(const Address &address)
uint16_t GetDestinationPort(void) const
Definition: udp-header.cc:70
void SetDatagramTag(uint16_t datagramTag)
Set the datagram tag.
void SetEcn(uint8_t ecn)
Set the ECN (2bits).
6LoWPAN FRAG1 header - see RFC 4944
uint32_t CompressLowPanHc1(Ptr< Packet > packet, Address const &src, Address const &dst)
Compress the headers according to HC1 compression.
uint8_t GetDatagramOffset(void) const
Get the datagram offset.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:455
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: uinteger.h:45
virtual void SetReceiveCallback(NetDevice::ReceiveCallback cb)
LowPanHc1Addr_e GetSrcCompression() const
Get Source Compression type.
a unique identifier for an interface.
Definition: type-id.h:51
static const uint8_t PROT_NUMBER
protocol number (0x11)
void SetDestinationAddress(Ipv6Address dst)
Set the "Destination address" field.
Definition: ipv6-header.cc:106
TypeId SetParent(TypeId tid)
Definition: type-id.cc:631
uint32_t m_ifIndex
Interface index.
UDP LOWPAN_NHC Extension Header Encoding - see RFC 6282.
void SetC(bool cField)
Set the C (Checksum).
uint8_t DecompressLowPanNhc(Ptr< Packet > packet, Address const &src, Address const &dst, Ipv6Address srcAddress, Ipv6Address dstAddress)
Decompress the headers according to NHC compression.
static const uint16_t PROT_NUMBER
The protocol number for IPv6 (0x86DD).
virtual void SetAddress(Address address)
Set the address of this interface.
void DecompressLowPanHc1(Ptr< Packet > packet, Address const &src, Address const &dst)
Decompress the headers according to HC1 compression.
void SetNextHeader(uint8_t nextHeader)
Set the Next Header value.
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
Ipv6Address GetDestinationAddress(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:111
void SetDam(HeaderCompression_e damField)
Set the DAM (Destination Address Mode) compression.
MapFragments_t m_fragments
Fragments hold to be rebuilt.
Ptr< UniformRandomVariable > m_rng
Rng for the fragments tag.
void SetFlowLabel(uint32_t flowLabel)
Set the Flow Label value.
virtual void DoDispose(void)
Destructor implementation.
void SetDatagramTag(uint16_t datagramTag)
Set the datagram tag.
uint16_t GetChecksum(void) const
Get the Checksum field value.