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  .SetGroupName ("SixLowPan")
54  .AddConstructor<SixLowPanNetDevice> ()
55  .AddAttribute ("Rfc6282", "Use RFC6282 (IPHC) if true, RFC4944 (HC1) otherwise.",
56  BooleanValue (true),
59  .AddAttribute ("OmitUdpChecksum",
60  "Omit the UDP checksum in IPHC compression.",
61  BooleanValue (true),
64  .AddAttribute ("FragmentReassemblyListSize", "The maximum size of the reassembly buffer (in packets). Zero meaning infinite.",
65  UintegerValue (0),
67  MakeUintegerChecker<uint16_t> ())
68  .AddAttribute ("FragmentExpirationTimeout",
69  "When this timeout expires, the fragments will be cleared from the buffer.",
70  TimeValue (Seconds (60)),
72  MakeTimeChecker ())
73  .AddAttribute ("CompressionThreshold",
74  "The minimum MAC layer payload size.",
75  UintegerValue (0x0),
77  MakeUintegerChecker<uint32_t> ())
78  .AddAttribute ("ForceEtherType",
79  "Force a specific EtherType in L2 frames.",
80  BooleanValue (false),
83  .AddAttribute ("EtherType",
84  "The specific EtherType to be used in L2 frames.",
85  UintegerValue (0xFFFF),
87  MakeUintegerChecker<uint16_t> ())
88  .AddTraceSource ("Tx",
89  "Send - packet (including 6LoWPAN header), "
90  "SixLoWPanNetDevice Ptr, interface index.",
92  "ns3::SixLowPanNetDevice::RxTxTracedCallback")
93  .AddTraceSource ("Rx",
94  "Receive - packet (including 6LoWPAN header), "
95  "SixLoWPanNetDevice Ptr, interface index.",
97  "ns3::SixLowPanNetDevice::RxTxTracedCallback")
98  .AddTraceSource ("Drop",
99  "Drop - DropReason, packet (including 6LoWPAN header), "
100  "SixLoWPanNetDevice Ptr, interface index.",
102  "ns3::SixLowPanNetDevice::DropTracedCallback")
103  ;
104  return tid;
105 }
106 
108  : m_node (0),
109  m_netDevice (0),
110  m_ifIndex (0)
111 {
112  NS_LOG_FUNCTION (this);
113  m_netDevice = 0;
114  m_rng = CreateObject<UniformRandomVariable> ();
115 }
116 
118 {
119  NS_LOG_FUNCTION (this);
120  return m_netDevice;
121 }
122 
124 {
125  NS_LOG_FUNCTION (this << device);
126  m_netDevice = device;
127 
128  NS_LOG_DEBUG ("RegisterProtocolHandler for " << device->GetInstanceTypeId ().GetName ());
129 
130  uint16_t protocolType = 0;
131  if ( m_forceEtherType )
132  {
133  protocolType = m_etherType;
134  }
136  this),
137  protocolType, device, false);
138 }
139 
140 int64_t SixLowPanNetDevice::AssignStreams (int64_t stream)
141 {
142  NS_LOG_FUNCTION (this << stream);
143  m_rng->SetStream (stream);
144  return 1;
145 }
146 
148 {
149  NS_LOG_FUNCTION (this);
150 
151  m_netDevice = 0;
152  m_node = 0;
153 
154  for (MapFragmentsTimersI_t iter = m_fragmentsTimers.begin (); iter != m_fragmentsTimers.end (); iter++)
155  {
156  iter->second.Cancel ();
157  }
158  m_fragmentsTimers.clear ();
159 
160  for (MapFragmentsI_t iter = m_fragments.begin (); iter != m_fragments.end (); iter++)
161  {
162  iter->second = 0;
163  }
164  m_fragments.clear ();
165 
167 }
168 
170  Ptr<const Packet> packet,
171  uint16_t protocol,
172  Address const &src,
173  Address const &dst,
174  PacketType packetType)
175 {
176  NS_LOG_FUNCTION (this << incomingPort << packet << protocol << src << dst);
177  NS_LOG_DEBUG ("UID is " << packet->GetUid ());
178 
179  uint8_t dispatchRawVal = 0;
180  SixLowPanDispatch::Dispatch_e dispatchVal;
181  Ptr<Packet> copyPkt = packet->Copy ();
182 
184 
185  copyPkt->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
186  dispatchVal = SixLowPanDispatch::GetDispatchType (dispatchRawVal);
187  bool isPktDecompressed = false;
188  bool fragmented = false;
189 
190  NS_LOG_DEBUG ( "Packet received: " << *copyPkt );
191  NS_LOG_DEBUG ( "Packet length: " << copyPkt->GetSize () );
192  NS_LOG_DEBUG ( "Dispatches: " << int(dispatchRawVal) << " - " << int(dispatchVal) );
193 
194  if ( dispatchVal == SixLowPanDispatch::LOWPAN_FRAG1 )
195  {
196  isPktDecompressed = ProcessFragment (copyPkt, src, dst, true);
197  fragmented = true;
198  }
199  else if ( dispatchVal == SixLowPanDispatch::LOWPAN_FRAGN )
200  {
201  isPktDecompressed = ProcessFragment (copyPkt, src, dst, false);
202  fragmented = true;
203  }
204  if ( fragmented )
205  {
206  if ( !isPktDecompressed )
207  {
208  return;
209  }
210  else
211  {
212  copyPkt->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
213  dispatchVal = SixLowPanDispatch::GetDispatchType (dispatchRawVal);
214  }
215  }
216 
217  switch ( dispatchVal )
218  {
220  NS_LOG_DEBUG ("Unsupported 6LoWPAN encoding: MESH, dropping.");
222  break;
224  NS_LOG_DEBUG ("Unsupported 6LoWPAN encoding: BC0, dropping.");
226  break;
228  NS_LOG_DEBUG ( "Packet without compression. Length: " << copyPkt->GetSize () );
229  {
230  SixLowPanIpv6 uncompressedHdr;
231  copyPkt->RemoveHeader(uncompressedHdr);
232  isPktDecompressed = true;
233  }
234  break;
236  DecompressLowPanHc1 (copyPkt, src, dst);
237  isPktDecompressed = true;
238  break;
240  DecompressLowPanIphc (copyPkt, src, dst);
241  isPktDecompressed = true;
242  break;
243  default:
244  NS_LOG_DEBUG ("Unsupported 6LoWPAN encoding: dropping.");
246  break;
247  }
248 
249  if ( !isPktDecompressed )
250  {
251  return;
252  }
253 
254  NS_LOG_DEBUG ( "Packet decompressed length: " << copyPkt->GetSize () );
255  NS_LOG_DEBUG ( "Packet decompressed received: " << *copyPkt );
256 
257  if (!m_promiscRxCallback.IsNull ())
258  {
259  m_promiscRxCallback (this, copyPkt, Ipv6L3Protocol::PROT_NUMBER, src, dst, packetType);
260  }
261 
262  m_rxCallback (this, copyPkt, Ipv6L3Protocol::PROT_NUMBER, src);
263 
264  return;
265 }
266 
267 void SixLowPanNetDevice::SetIfIndex (const uint32_t index)
268 {
269  NS_LOG_FUNCTION (this << index);
270  m_ifIndex = index;
271 }
272 
273 uint32_t SixLowPanNetDevice::GetIfIndex (void) const
274 {
275  NS_LOG_FUNCTION (this);
276  return m_ifIndex;
277 }
278 
280 {
281  NS_LOG_FUNCTION (this);
282  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
283 
284  return m_netDevice->GetChannel ();
285 }
286 
288 {
289  NS_LOG_FUNCTION (this << address);
290  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
291 
292  m_netDevice->SetAddress (address);
293 }
294 
296 {
297  NS_LOG_FUNCTION (this);
298  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
299 
300  return m_netDevice->GetAddress ();
301 }
302 
303 bool SixLowPanNetDevice::SetMtu (const uint16_t mtu)
304 {
305  NS_LOG_FUNCTION (this << mtu);
306  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
307 
308  return m_netDevice->SetMtu (mtu);
309 }
310 
311 uint16_t SixLowPanNetDevice::GetMtu (void) const
312 {
313  NS_LOG_FUNCTION (this);
314 
315  uint16_t mtu = m_netDevice->GetMtu ();
316 
317  // RFC 4944, section 4.
318  if (mtu < 1280)
319  {
320  mtu = 1280;
321  }
322  return mtu;
323 }
324 
326 {
327  NS_LOG_FUNCTION (this);
328  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
329 
330  return m_netDevice->IsLinkUp ();
331 }
332 
334 {
335  NS_LOG_FUNCTION (this);
336  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
337 
338  return m_netDevice->AddLinkChangeCallback (callback);
339 }
340 
342 {
343  NS_LOG_FUNCTION (this);
344  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
345 
346  return m_netDevice->IsBroadcast ();
347 }
348 
350 {
351  NS_LOG_FUNCTION (this);
352  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
353 
354  return m_netDevice->GetBroadcast ();
355 }
356 
358 {
359  NS_LOG_FUNCTION (this);
360  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
361 
362  return m_netDevice->IsMulticast ();
363 }
364 
366 {
367  NS_LOG_FUNCTION (this << multicastGroup);
368  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
369 
370  return m_netDevice->GetMulticast (multicastGroup);
371 }
372 
374 {
375  NS_LOG_FUNCTION (this << addr);
376  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
377 
378  return m_netDevice->GetMulticast (addr);
379 }
380 
382 {
383  NS_LOG_FUNCTION (this);
384  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
385 
386  return m_netDevice->IsPointToPoint ();
387 }
388 
390 {
391  NS_LOG_FUNCTION (this);
392  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
393 
394  return m_netDevice->IsBridge ();
395 }
396 
398  const Address& dest,
399  uint16_t protocolNumber)
400 {
401  NS_LOG_FUNCTION (this << *packet << dest << protocolNumber);
402  bool ret = false;
403  Address src;
404 
405  ret = DoSend (packet, src, dest, protocolNumber, false);
406  return ret;
407 }
408 
410  const Address& src,
411  const Address& dest,
412  uint16_t protocolNumber)
413 {
414  NS_LOG_FUNCTION (this << *packet << src << dest << protocolNumber);
415  bool ret = false;
416 
417  ret = DoSend (packet, src, dest, protocolNumber, true);
418  return ret;
419 }
420 
422  const Address& src,
423  const Address& dest,
424  uint16_t protocolNumber,
425  bool doSendFrom)
426 {
427  NS_LOG_FUNCTION (this << *packet << src << dest << protocolNumber << doSendFrom);
428  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
429 
430  Ptr<Packet> origPacket = packet->Copy ();
431  uint32_t origHdrSize = 0;
432  uint32_t origPacketSize = packet->GetSize ();
433  bool ret = false;
434 
435  if (m_forceEtherType)
436  {
437  protocolNumber = m_etherType;
438  }
439 
440  if (m_useIphc)
441  {
442  origHdrSize += CompressLowPanIphc (packet, m_netDevice->GetAddress (), dest);
443  }
444  else
445  {
446  origHdrSize += CompressLowPanHc1 (packet, m_netDevice->GetAddress (), dest);
447  }
448 
449  if ( packet->GetSize () > m_netDevice->GetMtu () )
450  {
451  NS_LOG_LOGIC ("Fragmentation: Packet size " << packet->GetSize () << " - Mtu " << m_netDevice->GetMtu () );
452  // fragment
453  std::list<Ptr<Packet> > fragmentList;
454  DoFragmentation (packet, origPacketSize, origHdrSize, fragmentList);
455  std::list<Ptr<Packet> >::iterator it;
456  bool success = true;
457  for ( it = fragmentList.begin (); it != fragmentList.end (); it++ )
458  {
459  NS_LOG_DEBUG ( "SixLowPanNetDevice::Send (Fragment) " << **it );
461  if (doSendFrom)
462  {
463  success &= m_netDevice->SendFrom (*it, src, dest, protocolNumber);
464  }
465  else
466  {
467  success &= m_netDevice->Send (*it, dest, protocolNumber);
468  }
469  }
470  ret = success;
471  }
472  else
473  {
474  if (packet->GetSize () < m_compressionThreshold)
475  {
476  NS_LOG_LOGIC ("Compressed packet too short, using uncompressed one");
477  packet = origPacket;
478  SixLowPanIpv6 ipv6UncompressedHdr;
479  packet->AddHeader (ipv6UncompressedHdr);
480  }
481 
483  if (doSendFrom)
484  {
485  NS_LOG_DEBUG ( "SixLowPanNetDevice::SendFrom " << m_node->GetId () << " " << *packet );
486  ret = m_netDevice->SendFrom (packet, src, dest, protocolNumber);
487  }
488  else
489  {
490  NS_LOG_DEBUG ( "SixLowPanNetDevice::Send " << m_node->GetId () << " " << *packet );
491  ret = m_netDevice->Send (packet, dest, protocolNumber);
492  }
493  }
494 
495  return ret;
496 }
497 
499 {
500  NS_LOG_FUNCTION (this);
501  return m_node;
502 }
503 
505 {
506  NS_LOG_FUNCTION (this << node);
507  m_node = node;
508 }
509 
511 {
512  NS_LOG_FUNCTION (this);
513  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
514 
515  return m_netDevice->NeedsArp ();
516 }
517 
519 {
520  NS_LOG_FUNCTION (this << &cb);
521  m_rxCallback = cb;
522 }
523 
525 {
526  NS_LOG_FUNCTION (this << &cb);
527  m_promiscRxCallback = cb;
528 }
529 
531 {
532  NS_LOG_FUNCTION (this);
533  return true;
534 }
535 
536 uint32_t
538 {
539  NS_LOG_FUNCTION (this << *packet << src << dst);
540 
541  Ipv6Header ipHeader;
542  SixLowPanHc1 hc1Header;
543  uint32_t size = 0;
544 
545  if ( packet->PeekHeader (ipHeader) != 0 )
546  {
547  packet->RemoveHeader (ipHeader);
548  size += ipHeader.GetSerializedSize ();
549 
550  hc1Header.SetHopLimit (ipHeader.GetHopLimit ());
551 
552  uint8_t bufOne[16];
553  uint8_t bufTwo[16];
554  Ipv6Address srcAddr = ipHeader.GetSourceAddress ();
555  srcAddr.GetBytes (bufOne);
556  Ipv6Address mySrcAddr = MakeLinkLocalAddressFromMac (src);
557 
558  NS_LOG_LOGIC ("Checking source compression: " << mySrcAddr << " - " << srcAddr );
559 
560  mySrcAddr.GetBytes (bufTwo);
561  bool isSrcSrc = (memcmp (bufOne + 8, bufTwo + 8, 8) == 0);
562 
563  if (srcAddr.IsLinkLocal () && isSrcSrc )
564  {
566  }
567  else if (srcAddr.IsLinkLocal () )
568  {
570  hc1Header.SetSrcInterface (bufOne + 8);
571  }
572  else if ( isSrcSrc )
573  {
575  hc1Header.SetSrcPrefix (bufOne);
576  }
577  else
578  {
580  hc1Header.SetSrcInterface (bufOne + 8);
581  hc1Header.SetSrcPrefix (bufOne);
582  }
583 
584  Ipv6Address dstAddr = ipHeader.GetDestinationAddress ();
585  dstAddr.GetBytes (bufOne);
586  Ipv6Address myDstAddr = MakeLinkLocalAddressFromMac (dst);
587 
588  NS_LOG_LOGIC ("Checking destination compression: " << myDstAddr << " - " << dstAddr );
589 
590  myDstAddr.GetBytes (bufTwo);
591  bool isDstDst = (memcmp (bufOne + 8, bufTwo + 8, 8) == 0);
592 
593  if (dstAddr.IsLinkLocal () && isDstDst )
594  {
596  }
597  else if (dstAddr.IsLinkLocal () )
598  {
600  hc1Header.SetDstInterface (bufOne + 8);
601  }
602  else if ( isDstDst )
603  {
605  hc1Header.SetDstPrefix (bufOne);
606  }
607  else
608  {
610  hc1Header.SetDstInterface (bufOne + 8);
611  hc1Header.SetDstPrefix (bufOne);
612  }
613 
614  if ( (ipHeader.GetFlowLabel () == 0) && (ipHeader.GetTrafficClass () == 0) )
615  {
616  hc1Header.SetTcflCompression (true);
617  }
618  else
619  {
620  hc1Header.SetTcflCompression (false);
621  hc1Header.SetTrafficClass (ipHeader.GetTrafficClass ());
622  hc1Header.SetFlowLabel (ipHeader.GetFlowLabel ());
623  }
624 
625  uint8_t nextHeader = ipHeader.GetNextHeader ();
626  hc1Header.SetNextHeader (nextHeader);
627 
628  // \todo implement HC2 compression
629  hc1Header.SetHc2HeaderPresent (false);
630 
631  NS_LOG_DEBUG ("HC1 Compression - HC1 header size = " << hc1Header.GetSerializedSize () );
632  NS_LOG_DEBUG ("HC1 Compression - packet size = " << packet->GetSize () );
633 
634  packet->AddHeader (hc1Header);
635 
636  return size;
637  }
638 
639  return 0;
640 }
641 
642 void
644 {
645  NS_LOG_FUNCTION (this << *packet << src << dst);
646 
647  Ipv6Header ipHeader;
648  SixLowPanHc1 encoding;
649 
650  uint32_t ret = packet->RemoveHeader (encoding);
651  NS_LOG_DEBUG ("removed " << ret << " bytes - pkt is " << *packet);
652  NS_UNUSED (ret);
653 
654  ipHeader.SetHopLimit (encoding.GetHopLimit ());
655 
656  switch (encoding.GetSrcCompression ())
657  {
658  const uint8_t* interface;
659  const uint8_t* prefix;
660  uint8_t address[16];
661 
663  prefix = encoding.GetSrcPrefix ();
664  interface = encoding.GetSrcInterface ();
665  for (int j = 0; j < 8; j++)
666  {
667  address[j + 8] = interface[j];
668  address[j] = prefix[j];
669  }
670  ipHeader.SetSourceAddress ( Ipv6Address (address) );
671  break;
673  prefix = encoding.GetSrcPrefix ();
674  for (int j = 0; j < 8; j++)
675  {
676  address[j + 8] = 0;
677  address[j] = prefix[j];
678  }
679  ipHeader.SetSourceAddress ( MakeGlobalAddressFromMac (src, Ipv6Address (address)));
680  break;
682  interface = encoding.GetSrcInterface ();
683  address[0] = 0xfe;
684  address[1] = 0x80;
685  for (int j = 0; j < 8; j++)
686  {
687  address[j + 8] = interface[j];
688  }
689  ipHeader.SetSourceAddress ( Ipv6Address (address) );
690  break;
693  break;
694  }
695 
696  switch (encoding.GetDstCompression ())
697  {
698  const uint8_t* interface;
699  const uint8_t* prefix;
700  uint8_t address[16];
701 
703  prefix = encoding.GetDstPrefix ();
704  interface = encoding.GetDstInterface ();
705  for (int j = 0; j < 8; j++)
706  {
707  address[j + 8] = interface[j];
708  address[j] = prefix[j];
709  }
710  ipHeader.SetDestinationAddress ( Ipv6Address (address) );
711  break;
713  prefix = encoding.GetDstPrefix ();
714  for (int j = 0; j < 8; j++)
715  {
716  address[j + 8] = 0;
717  address[j] = prefix[j];
718  }
719  ipHeader.SetDestinationAddress ( MakeGlobalAddressFromMac (dst, Ipv6Address (address)));
720  break;
722  interface = encoding.GetDstInterface ();
723  address[0] = 0xfe;
724  address[1] = 0x80;
725  for (int j = 0; j < 8; j++)
726  {
727  address[j + 8] = interface[j];
728  }
729  ipHeader.SetDestinationAddress ( Ipv6Address (address) );
730  break;
733  break;
734  }
735 
736  if ( !encoding.IsTcflCompression () )
737  {
738  ipHeader.SetFlowLabel (encoding.GetFlowLabel ());
739  ipHeader.SetTrafficClass (encoding.GetTrafficClass ());
740  }
741  else
742  {
743  ipHeader.SetFlowLabel (0);
744  ipHeader.SetTrafficClass (0);
745  }
746 
747  ipHeader.SetNextHeader (encoding.GetNextHeader ());
748 
749  ipHeader.SetPayloadLength (packet->GetSize ());
750 
751  NS_ASSERT_MSG (encoding.IsHc2HeaderPresent () == false,
752  "6LoWPAN: error in decompressing HC1 encoding, unsupported L4 compressed header present.");
753 
754  packet->AddHeader (ipHeader);
755 
756  NS_LOG_DEBUG ( "Rebuilt packet: " << *packet << " Size " << packet->GetSize () );
757 }
758 
759 uint32_t
761 {
762  NS_LOG_FUNCTION (this << *packet << src << dst);
763 
764  Ipv6Header ipHeader;
765  SixLowPanIphc iphcHeader;
766  uint32_t size = 0;
767 
768 
769  if ( packet->PeekHeader (ipHeader) != 0 )
770  {
771  packet->RemoveHeader (ipHeader);
772  size += ipHeader.GetSerializedSize ();
773 
774  // Set the TF field
775  if ( (ipHeader.GetFlowLabel () == 0) && (ipHeader.GetTrafficClass () == 0) )
776  {
777  iphcHeader.SetTf (SixLowPanIphc::TF_ELIDED);
778  }
779  else if ( (ipHeader.GetFlowLabel () != 0) && (ipHeader.GetTrafficClass () != 0) )
780  {
781  iphcHeader.SetTf (SixLowPanIphc::TF_FULL);
782  iphcHeader.SetEcn ( (ipHeader.GetTrafficClass () & 0xC0) >> 6);
783  iphcHeader.SetDscp ( ipHeader.GetTrafficClass () & 0x3F );
784  iphcHeader.SetFlowLabel (ipHeader.GetFlowLabel ());
785  }
786  else if ( (ipHeader.GetFlowLabel () == 0) && (ipHeader.GetTrafficClass () != 0) )
787  {
788  iphcHeader.SetTf (SixLowPanIphc::TF_FL_ELIDED);
789  iphcHeader.SetEcn ( (ipHeader.GetTrafficClass () & 0xC0) >> 6);
790  iphcHeader.SetDscp ( ipHeader.GetTrafficClass () & 0x3F );
791  }
792  else
793  {
795  iphcHeader.SetEcn ( (ipHeader.GetTrafficClass () & 0xC0) >> 6);
796  iphcHeader.SetFlowLabel (ipHeader.GetFlowLabel ());
797  }
798 
799  // Set the NH field and NextHeader
800 
801  uint8_t nextHeader = ipHeader.GetNextHeader ();
802  if (CanCompressLowPanNhc (nextHeader))
803  {
804  if (nextHeader == Ipv6Header::IPV6_UDP)
805  {
806  iphcHeader.SetNh (true);
807  size += CompressLowPanUdpNhc (packet, m_omitUdpChecksum);
808  }
809  else if (nextHeader == Ipv6Header::IPV6_IPV6)
810  {
811  iphcHeader.SetNh (true);
812  size += CompressLowPanIphc (packet, src, dst);
813  }
814  else
815  {
816  uint32_t sizeNhc = CompressLowPanNhc (packet, nextHeader, src, dst);
817  // the compression might fail due to Extension header size.
818  if (sizeNhc)
819  {
820  iphcHeader.SetNh (true);
821  size += sizeNhc;
822  }
823  else
824  {
825  iphcHeader.SetNh (false);
826  iphcHeader.SetNextHeader (nextHeader);
827  }
828  }
829  }
830  else
831  {
832  iphcHeader.SetNh (false);
833  iphcHeader.SetNextHeader (nextHeader);
834  }
835 
836 
837  // Set the HLIM field
838  if (ipHeader.GetHopLimit () == 1)
839  {
841  }
842  else if (ipHeader.GetHopLimit () == 0x40)
843  {
845  }
846  else if (ipHeader.GetHopLimit () == 0xFF)
847  {
849  }
850  else
851  {
852  iphcHeader.SetHlim (SixLowPanIphc::HLIM_INLINE);
853  // Set the HopLimit
854  iphcHeader.SetHopLimit (ipHeader.GetHopLimit ());
855  }
856 
857  // \todo Add the check of CID if there is context-based compression
858  // Set the CID field
859  iphcHeader.SetCid (false);
860 
861  // \todo Add the check of SAC if there is context-based compression
862  // Set the SAC field
863  iphcHeader.SetSac (false);
864 
865  uint8_t addressBuf[16];
866  uint8_t unicastAddrCheckerBuf[16];
867  Ipv6Address srcAddr = ipHeader.GetSourceAddress ();
868  srcAddr.GetBytes (addressBuf);
869 
870  Ipv6Address checker = Ipv6Address ("fe80:0000:0000:0000:0000:00ff:fe00:1");
871  checker.GetBytes (unicastAddrCheckerBuf);
872 
873  // \todo Add the check of SAC if there is context-based compression
874  // Set the Source Address
875  iphcHeader.SetSrcAddress (srcAddr);
876 
877  Ipv6Address mySrcAddr = MakeLinkLocalAddressFromMac (src);
878  NS_LOG_LOGIC ("Checking source compression: " << mySrcAddr << " - " << srcAddr );
879 
880  if ( mySrcAddr == srcAddr )
881  {
882  iphcHeader.SetSam (SixLowPanIphc::HC_COMPR_0);
883  }
884  else if (memcmp (addressBuf, unicastAddrCheckerBuf, 14) == 0)
885  {
886  iphcHeader.SetSam (SixLowPanIphc::HC_COMPR_16);
887  }
888  else if ( srcAddr.IsLinkLocal () )
889  {
890  iphcHeader.SetSam (SixLowPanIphc::HC_COMPR_64);
891  }
892  else
893  {
894  iphcHeader.SetSam (SixLowPanIphc::HC_INLINE);
895  }
896 
897  // Set the M field
898  if (ipHeader.GetDestinationAddress ().IsMulticast ())
899  {
900  iphcHeader.SetM (true);
901  }
902  else
903  {
904  iphcHeader.SetM (false);
905  }
906 
907  // \todo Add the check of DAC if there is context-based compression
908  // Set the DAC field
909  iphcHeader.SetDac (false);
910 
911  Ipv6Address dstAddr = ipHeader.GetDestinationAddress ();
912  dstAddr.GetBytes (addressBuf);
913 
914  // \todo Add the check of DAC if there is context-based compression
915  // Set the Destination Address
916  iphcHeader.SetDstAddress (dstAddr);
917 
918  Ipv6Address myDstAddr = MakeLinkLocalAddressFromMac (dst);
919  NS_LOG_LOGIC ("Checking destination compression: " << myDstAddr << " - " << dstAddr );
920 
921  if ( !iphcHeader.GetM () )
922  // Unicast address
923  {
924  if ( myDstAddr == dstAddr )
925  {
926  iphcHeader.SetDam (SixLowPanIphc::HC_COMPR_0);
927  }
928  else if (memcmp (addressBuf, unicastAddrCheckerBuf, 14) == 0)
929  {
930  iphcHeader.SetDam (SixLowPanIphc::HC_COMPR_16);
931  }
932  else if ( dstAddr.IsLinkLocal () )
933  {
934  iphcHeader.SetDam (SixLowPanIphc::HC_COMPR_64);
935  }
936  else
937  {
938  iphcHeader.SetDam (SixLowPanIphc::HC_INLINE);
939  }
940  }
941  else
942  {
943  // Multicast address
944  uint8_t multicastAddrCheckerBuf[16];
945  Ipv6Address multicastCheckAddress = Ipv6Address ("ff02::1");
946  multicastCheckAddress.GetBytes (multicastAddrCheckerBuf);
947 
948  // The address takes the form ff02::00XX.
949  if ( memcmp (addressBuf, multicastAddrCheckerBuf, 15) == 0 )
950  {
951  iphcHeader.SetDam (SixLowPanIphc::HC_COMPR_0);
952  }
953  // The address takes the form ffXX::00XX:XXXX.
954  // ffXX:0000:0000:0000:0000:0000:00XX:XXXX.
955  else if ( (addressBuf[0] == multicastAddrCheckerBuf[0])
956  && (memcmp (addressBuf + 2, multicastAddrCheckerBuf + 2, 11) == 0) )
957  {
958  iphcHeader.SetDam (SixLowPanIphc::HC_COMPR_16);
959  }
960  // The address takes the form ffXX::00XX:XXXX:XXXX.
961  // ffXX:0000:0000:0000:0000:00XX:XXXX:XXXX.
962  else if ( (addressBuf[0] == multicastAddrCheckerBuf[0])
963  && (memcmp (addressBuf + 2, multicastAddrCheckerBuf + 2, 9) == 0) )
964  {
965  iphcHeader.SetDam (SixLowPanIphc::HC_COMPR_64);
966  }
967  else
968  {
969  iphcHeader.SetDam (SixLowPanIphc::HC_INLINE);
970  }
971  }
972 
973  NS_LOG_DEBUG ("IPHC Compression - IPHC header size = " << iphcHeader.GetSerializedSize () );
974  NS_LOG_DEBUG ("IPHC Compression - packet size = " << packet->GetSize () );
975 
976  packet->AddHeader (iphcHeader);
977 
978  NS_LOG_DEBUG ("Packet after IPHC compression: " << *packet);
979 
980  return size;
981  }
982 
983  return 0;
984 }
985 
986 bool
988 {
989  bool ret = false;
990 
991  switch (nextHeader)
992  {
998  ret = true;
999  break;
1001  default:
1002  ret = false;
1003  }
1004  return ret;
1005 }
1006 
1007 void
1009 {
1010  NS_LOG_FUNCTION (this << *packet << src << dst);
1011 
1012  Ipv6Header ipHeader;
1013  SixLowPanIphc encoding;
1014 
1015  uint32_t ret = packet->RemoveHeader (encoding);
1016  NS_LOG_DEBUG ("removed " << ret << " bytes - pkt is " << *packet);
1017  NS_UNUSED (ret);
1018 
1019  // Hop Limit
1020  ipHeader.SetHopLimit (encoding.GetHopLimit ());
1021 
1022  // Source address
1023  if ( encoding.GetSac () )
1024  {
1025  if ( encoding.GetSam () == SixLowPanIphc::HC_INLINE )
1026  {
1027  ipHeader.SetSourceAddress ( Ipv6Address::GetAny () );
1028  }
1029  else
1030  {
1031  NS_ABORT_MSG ("SAC option not yet implemented");
1032  }
1033  }
1034  else
1035  {
1036  if ( encoding.GetSam () == SixLowPanIphc::HC_COMPR_0 )
1037  {
1039  }
1040  else
1041  {
1042  ipHeader.SetSourceAddress ( encoding.GetSrcAddress () );
1043  }
1044  }
1045  // Destination address
1046  if ( encoding.GetDac () )
1047  {
1048  if ((encoding.GetDam () == SixLowPanIphc::HC_INLINE && !encoding.GetM ())
1049  || (encoding.GetDam () == SixLowPanIphc::HC_COMPR_64 && encoding.GetM ())
1050  || (encoding.GetDam () == SixLowPanIphc::HC_COMPR_16 && encoding.GetM ())
1051  || (encoding.GetDam () == SixLowPanIphc::HC_COMPR_0 && encoding.GetM ()) )
1052  {
1053  NS_ABORT_MSG ("Reserved code found");
1054  }
1055  else
1056  {
1057  NS_ABORT_MSG ("DAC option not yet implemented");
1058  }
1059  }
1060  else
1061  {
1062  if ( !encoding.GetM () && encoding.GetDam () == SixLowPanIphc::HC_COMPR_0 )
1063  {
1065  }
1066  else
1067  {
1068  ipHeader.SetDestinationAddress ( encoding.GetDstAddress () );
1069  }
1070  }
1071 
1072  // Traffic class and Flow Label
1073  uint8_t traf = 0x00;
1074  switch (encoding.GetTf ())
1075  {
1077  traf |= encoding.GetEcn ();
1078  traf = ( traf << 6 ) | encoding.GetDscp ();
1079  ipHeader.SetTrafficClass (traf);
1080  ipHeader.SetFlowLabel ( encoding.GetFlowLabel () & 0xfff ); //Add 4-bit pad
1081  break;
1083  traf |= encoding.GetEcn ();
1084  traf <<= 2; // Add 2-bit pad
1085  ipHeader.SetTrafficClass (traf);
1086  ipHeader.SetFlowLabel (encoding.GetFlowLabel ());
1087  break;
1089  traf |= encoding.GetEcn ();
1090  traf = ( traf << 6 ) | encoding.GetDscp ();
1091  ipHeader.SetTrafficClass (traf);
1092  ipHeader.SetFlowLabel (0);
1093  break;
1095  ipHeader.SetFlowLabel (0);
1096  ipHeader.SetTrafficClass (0);
1097  break;
1098  }
1099 
1100  if ( encoding.GetNh () )
1101  {
1102  // Next Header
1103  uint8_t dispatchRawVal = 0;
1105 
1106  packet->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
1107  dispatchVal = SixLowPanDispatch::GetNhcDispatchType (dispatchRawVal);
1108 
1109  if (dispatchVal == SixLowPanDispatch::LOWPAN_UDPNHC)
1110  {
1112  DecompressLowPanUdpNhc (packet, ipHeader.GetSourceAddress (), ipHeader.GetDestinationAddress ());
1113  }
1114  else
1115  {
1116  ipHeader.SetNextHeader (DecompressLowPanNhc (packet, src, dst, ipHeader.GetSourceAddress (), ipHeader.GetDestinationAddress ()));
1117  }
1118  }
1119  else
1120  {
1121  ipHeader.SetNextHeader (encoding.GetNextHeader ());
1122  }
1123 
1124  ipHeader.SetPayloadLength (packet->GetSize ());
1125 
1126  packet->AddHeader (ipHeader);
1127 
1128  NS_LOG_DEBUG ( "Rebuilt packet: " << *packet << " Size " << packet->GetSize () );
1129 
1130 }
1131 
1132 uint32_t
1133 SixLowPanNetDevice::CompressLowPanNhc (Ptr<Packet> packet, uint8_t headerType, Address const &src, Address const &dst)
1134 {
1135  NS_LOG_FUNCTION (this << *packet << int(headerType));
1136 
1137  SixLowPanNhcExtension nhcHeader;
1138  uint32_t size = 0;
1139  Buffer blob;
1140 
1141  if (headerType == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1142  {
1143  Ipv6ExtensionHopByHopHeader hopHeader;
1144  packet->PeekHeader (hopHeader);
1145  if (hopHeader.GetLength () >= 0xff)
1146  {
1147  NS_LOG_DEBUG ("LOWPAN_NHC MUST NOT be used to encode IPv6 Extension Headers "
1148  "that have more than 255 octets following the Length field after compression. "
1149  "Packet uncompressed.");
1150  return 0;
1151  }
1152 
1153  size += packet->RemoveHeader (hopHeader);
1155 
1156  // recursively compress other headers
1157  uint8_t nextHeader = hopHeader.GetNextHeader ();
1158  if (CanCompressLowPanNhc (nextHeader))
1159  {
1160  if (nextHeader == Ipv6Header::IPV6_UDP)
1161  {
1162  nhcHeader.SetNh (true);
1163  size += CompressLowPanUdpNhc (packet, m_omitUdpChecksum);
1164  }
1165  else if (nextHeader == Ipv6Header::IPV6_IPV6)
1166  {
1167  nhcHeader.SetNh (true);
1168  size += CompressLowPanIphc (packet, src, dst);
1169  }
1170  else
1171  {
1172  uint32_t sizeNhc = CompressLowPanNhc (packet, nextHeader, src, dst);
1173  // the compression might fail due to Extension header size.
1174  if (sizeNhc)
1175  {
1176  nhcHeader.SetNh (true);
1177  size += sizeNhc;
1178  }
1179  else
1180  {
1181  nhcHeader.SetNh (false);
1182  nhcHeader.SetNextHeader (nextHeader);
1183  }
1184  }
1185  }
1186  else
1187  {
1188  nhcHeader.SetNh (false);
1189  nhcHeader.SetNextHeader (nextHeader);
1190  }
1191 
1192  uint32_t blobSize = hopHeader.GetSerializedSize ();
1193  blob.AddAtStart (blobSize);
1194  hopHeader.Serialize (blob.Begin ());
1195  blob.RemoveAtStart (2);
1196  blobSize = blob.GetSize ();
1197  nhcHeader.SetBlob (blob.PeekData (), blobSize);
1198  }
1199  else if (headerType == Ipv6Header::IPV6_EXT_ROUTING)
1200  {
1201  Ipv6ExtensionRoutingHeader routingHeader;
1202  packet->PeekHeader (routingHeader);
1203  if (routingHeader.GetLength () >= 0xff)
1204  {
1205  NS_LOG_DEBUG ("LOWPAN_NHC MUST NOT be used to encode IPv6 Extension Headers "
1206  "that have more than 255 octets following the Length field after compression. "
1207  "Packet uncompressed.");
1208  return 0;
1209  }
1210 
1211  size += packet->RemoveHeader (routingHeader);
1213 
1214  // recursively compress other headers
1215  uint8_t nextHeader = routingHeader.GetNextHeader ();
1216  if (CanCompressLowPanNhc (nextHeader))
1217  {
1218  if (nextHeader == Ipv6Header::IPV6_UDP)
1219  {
1220  nhcHeader.SetNh (true);
1221  size += CompressLowPanUdpNhc (packet, m_omitUdpChecksum);
1222  }
1223  else if (nextHeader == Ipv6Header::IPV6_IPV6)
1224  {
1225  nhcHeader.SetNh (true);
1226  size += CompressLowPanIphc (packet, src, dst);
1227  }
1228  else
1229  {
1230  uint32_t sizeNhc = CompressLowPanNhc (packet, nextHeader, src, dst);
1231  // the compression might fail due to Extension header size.
1232  if (sizeNhc)
1233  {
1234  nhcHeader.SetNh (true);
1235  size += sizeNhc;
1236  }
1237  else
1238  {
1239  nhcHeader.SetNh (false);
1240  nhcHeader.SetNextHeader (nextHeader);
1241  }
1242  }
1243  }
1244  else
1245  {
1246  nhcHeader.SetNh (false);
1247  nhcHeader.SetNextHeader (nextHeader);
1248  }
1249 
1250  uint32_t blobSize = routingHeader.GetSerializedSize ();
1251  blob.AddAtStart (blobSize);
1252  routingHeader.Serialize (blob.Begin ());
1253  blob.RemoveAtStart (2);
1254  blobSize = blob.GetSize ();
1255  nhcHeader.SetBlob (blob.PeekData (), blobSize);
1256  }
1257  else if (headerType == Ipv6Header::IPV6_EXT_FRAGMENTATION)
1258  {
1259  Ipv6ExtensionFragmentHeader fragHeader;
1260  packet->PeekHeader (fragHeader);
1261  if (fragHeader.GetLength () >= 0xff)
1262  {
1263  NS_LOG_DEBUG ("LOWPAN_NHC MUST NOT be used to encode IPv6 Extension Headers "
1264  "that have more than 255 octets following the Length field after compression. "
1265  "Packet uncompressed.");
1266  return 0;
1267  }
1268  size += packet->RemoveHeader (fragHeader);
1270 
1271  // recursively compress other headers
1272  uint8_t nextHeader = fragHeader.GetNextHeader ();
1273  if (CanCompressLowPanNhc (nextHeader))
1274  {
1275  if (nextHeader == Ipv6Header::IPV6_UDP)
1276  {
1277  nhcHeader.SetNh (true);
1278  size += CompressLowPanUdpNhc (packet, m_omitUdpChecksum);
1279  }
1280  else if (nextHeader == Ipv6Header::IPV6_IPV6)
1281  {
1282  nhcHeader.SetNh (true);
1283  size += CompressLowPanIphc (packet, src, dst);
1284  }
1285  else
1286  {
1287  uint32_t sizeNhc = CompressLowPanNhc (packet, nextHeader, src, dst);
1288  // the compression might fail due to Extension header size.
1289  if (sizeNhc)
1290  {
1291  nhcHeader.SetNh (true);
1292  size += sizeNhc;
1293  }
1294  else
1295  {
1296  nhcHeader.SetNh (false);
1297  nhcHeader.SetNextHeader (nextHeader);
1298  }
1299  }
1300  }
1301  else
1302  {
1303  nhcHeader.SetNh (false);
1304  nhcHeader.SetNextHeader (nextHeader);
1305  }
1306 
1307  uint32_t blobSize = fragHeader.GetSerializedSize ();
1308  blob.AddAtStart (blobSize);
1309  fragHeader.Serialize (blob.Begin ());
1310  blob.RemoveAtStart (2);
1311  blobSize = blob.GetSize ();
1312  nhcHeader.SetBlob (blob.PeekData (), blobSize);
1313  }
1314  else if (headerType == Ipv6Header::IPV6_EXT_DESTINATION)
1315  {
1316  Ipv6ExtensionDestinationHeader destHeader;
1317  packet->PeekHeader (destHeader);
1318  if (destHeader.GetLength () >= 0xff)
1319  {
1320  NS_LOG_DEBUG ("LOWPAN_NHC MUST NOT be used to encode IPv6 Extension Headers "
1321  "that have more than 255 octets following the Length field after compression. "
1322  "Packet uncompressed.");
1323  return 0;
1324  }
1325  size += packet->RemoveHeader (destHeader);
1327 
1328  // recursively compress other headers
1329  uint8_t nextHeader = destHeader.GetNextHeader ();
1330  if (CanCompressLowPanNhc (nextHeader))
1331  {
1332  if (nextHeader == Ipv6Header::IPV6_UDP)
1333  {
1334  nhcHeader.SetNh (true);
1335  size += CompressLowPanUdpNhc (packet, m_omitUdpChecksum);
1336  }
1337  else if (nextHeader == Ipv6Header::IPV6_IPV6)
1338  {
1339  nhcHeader.SetNh (true);
1340  size += CompressLowPanIphc (packet, src, dst);
1341  }
1342  else
1343  {
1344  uint32_t sizeNhc = CompressLowPanNhc (packet, nextHeader, src, dst);
1345  // the compression might fail due to Extension header size.
1346  if (sizeNhc)
1347  {
1348  nhcHeader.SetNh (true);
1349  size += sizeNhc;
1350  }
1351  else
1352  {
1353  nhcHeader.SetNh (false);
1354  nhcHeader.SetNextHeader (nextHeader);
1355  }
1356  }
1357  }
1358  else
1359  {
1360  nhcHeader.SetNh (false);
1361  nhcHeader.SetNextHeader (nextHeader);
1362  }
1363 
1364  uint32_t blobSize = destHeader.GetSerializedSize ();
1365  blob.AddAtStart (blobSize);
1366  destHeader.Serialize (blob.Begin ());
1367  blob.RemoveAtStart (2);
1368  blobSize = blob.GetSize ();
1369  nhcHeader.SetBlob (blob.PeekData (), blobSize);
1370  }
1371  else if (headerType == Ipv6Header::IPV6_EXT_MOBILITY)
1372  {
1373  // \todo: IPv6 Mobility Header is not supported in ns-3
1374  NS_ABORT_MSG ("IPv6 Mobility Header is not supported in ns-3 yet");
1375  return 0;
1376  }
1377  else
1378  {
1379  NS_ABORT_MSG ("Unexpected Extension Header");
1380  }
1381 
1382  NS_LOG_DEBUG ("NHC Compression - NHC header size = " << nhcHeader.GetSerializedSize () );
1383  NS_LOG_DEBUG ("NHC Compression - packet size = " << packet->GetSize () );
1384 
1385  packet->AddHeader (nhcHeader);
1386 
1387  NS_LOG_DEBUG ("Packet after NHC compression: " << *packet);
1388  return size;
1389 }
1390 
1391 uint8_t
1392 SixLowPanNetDevice::DecompressLowPanNhc (Ptr<Packet> packet, Address const &src, Address const &dst, Ipv6Address srcAddress, Ipv6Address dstAddress)
1393 {
1394  NS_LOG_FUNCTION (this << *packet);
1395 
1396  SixLowPanNhcExtension encoding;
1397 
1398  uint32_t ret = packet->RemoveHeader (encoding);
1399  NS_LOG_DEBUG ("removed " << ret << " bytes - pkt is " << *packet);
1400  NS_UNUSED (ret);
1401 
1402  Ipv6ExtensionHopByHopHeader hopHeader;
1403  Ipv6ExtensionRoutingHeader routingHeader;
1404  Ipv6ExtensionFragmentHeader fragHeader;
1405  Ipv6ExtensionDestinationHeader destHeader;
1406 
1407  uint32_t blobSize;
1408  uint8_t blobData[260];
1409  blobSize = encoding.CopyBlob (blobData + 2, 260);
1410  uint8_t paddingSize = 0;
1411 
1412  uint8_t actualEncodedHeaderType = encoding.GetEid ();
1413  uint8_t actualHeaderType;
1414  Buffer blob;
1415 
1416  switch (actualEncodedHeaderType)
1417  {
1419  actualHeaderType = Ipv6Header::IPV6_EXT_HOP_BY_HOP;
1420  if ( encoding.GetNh () )
1421  {
1422  // Next Header
1423  uint8_t dispatchRawVal = 0;
1425 
1426  packet->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
1427  dispatchVal = SixLowPanDispatch::GetNhcDispatchType (dispatchRawVal);
1428 
1429  if (dispatchVal == SixLowPanDispatch::LOWPAN_UDPNHC)
1430  {
1431  blobData [0] = Ipv6Header::IPV6_UDP;
1432  DecompressLowPanUdpNhc (packet, srcAddress, dstAddress);
1433  }
1434  else
1435  {
1436  blobData [0] = DecompressLowPanNhc (packet, src, dst, srcAddress, dstAddress);
1437  }
1438  }
1439  else
1440  {
1441  blobData [0] = encoding.GetNextHeader ();
1442  }
1443 
1444  // manually add some padding if needed
1445  if ((blobSize + 2) % 8 > 0)
1446  {
1447  paddingSize = 8 - (blobSize + 2) % 8;
1448  }
1449  if (paddingSize == 1)
1450  {
1451  blobData[blobSize + 2] = 0;
1452  }
1453  else if (paddingSize > 1)
1454  {
1455  blobData[blobSize + 2] = 1;
1456  blobData[blobSize + 2 + 1] = paddingSize - 2;
1457  for (uint8_t i = 0; i < paddingSize - 2; i++)
1458  {
1459  blobData[blobSize + 2 + 2 + i] = 0;
1460  }
1461  }
1462  blobData [1] = ((blobSize + 2 + paddingSize) >> 3) - 1;
1463  blob.AddAtStart (blobSize + 2 + paddingSize);
1464  blob.Begin ().Write (blobData, blobSize + 2 + paddingSize);
1465  hopHeader.Deserialize (blob.Begin ());
1466 
1467  packet->AddHeader (hopHeader);
1468  break;
1469 
1471  actualHeaderType = Ipv6Header::IPV6_EXT_ROUTING;
1472  if ( encoding.GetNh () )
1473  {
1474  // Next Header
1475  uint8_t dispatchRawVal = 0;
1477 
1478  packet->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
1479  dispatchVal = SixLowPanDispatch::GetNhcDispatchType (dispatchRawVal);
1480 
1481  if (dispatchVal == SixLowPanDispatch::LOWPAN_UDPNHC)
1482  {
1483  blobData [0] = Ipv6Header::IPV6_UDP;
1484  DecompressLowPanUdpNhc (packet, srcAddress, dstAddress);
1485  }
1486  else
1487  {
1488  blobData [0] = DecompressLowPanNhc (packet, src, dst, srcAddress, dstAddress);
1489  }
1490  }
1491  else
1492  {
1493  blobData [0] = encoding.GetNextHeader ();
1494  }
1495  blobData [1] = ((blobSize + 2) >> 3) - 1;
1496  blob.AddAtStart (blobSize + 2);
1497  blob.Begin ().Write (blobData, blobSize + 2);
1498  routingHeader.Deserialize (blob.Begin ());
1499  packet->AddHeader (routingHeader);
1500  break;
1501 
1503  actualHeaderType = Ipv6Header::IPV6_EXT_FRAGMENTATION;
1504  if ( encoding.GetNh () )
1505  {
1506  // Next Header
1507  uint8_t dispatchRawVal = 0;
1509 
1510  packet->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
1511  dispatchVal = SixLowPanDispatch::GetNhcDispatchType (dispatchRawVal);
1512 
1513  if (dispatchVal == SixLowPanDispatch::LOWPAN_UDPNHC)
1514  {
1515  blobData [0] = Ipv6Header::IPV6_UDP;
1516  DecompressLowPanUdpNhc (packet, srcAddress, dstAddress);
1517  }
1518  else
1519  {
1520  blobData [0] = DecompressLowPanNhc (packet, src, dst, srcAddress, dstAddress);
1521  }
1522  }
1523  else
1524  {
1525  blobData [0] = encoding.GetNextHeader ();
1526  }
1527  blobData [1] = 0;
1528  fragHeader.Deserialize (blob.Begin ());
1529  packet->AddHeader (fragHeader);
1530  break;
1531 
1533  actualHeaderType = Ipv6Header::IPV6_EXT_DESTINATION;
1534  if ( encoding.GetNh () )
1535  {
1536  // Next Header
1537  uint8_t dispatchRawVal = 0;
1539 
1540  packet->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
1541  dispatchVal = SixLowPanDispatch::GetNhcDispatchType (dispatchRawVal);
1542 
1543  if (dispatchVal == SixLowPanDispatch::LOWPAN_UDPNHC)
1544  {
1545  blobData [0] = Ipv6Header::IPV6_UDP;
1546  DecompressLowPanUdpNhc (packet, srcAddress, dstAddress);
1547  }
1548  else
1549  {
1550  blobData [0] = DecompressLowPanNhc (packet, src, dst, srcAddress, dstAddress);
1551  }
1552  }
1553  else
1554  {
1555  blobData [0] = encoding.GetNextHeader ();
1556  }
1557 
1558  // manually add some padding if needed
1559  if ((blobSize + 2) % 8 > 0)
1560  {
1561  paddingSize = 8 - (blobSize + 2) % 8;
1562  }
1563  if (paddingSize == 1)
1564  {
1565  blobData[blobSize + 2] = 0;
1566  }
1567  else if (paddingSize > 1)
1568  {
1569  blobData[blobSize + 2] = 1;
1570  blobData[blobSize + 2 + 1] = paddingSize - 2;
1571  for (uint8_t i = 0; i < paddingSize - 2; i++)
1572  {
1573  blobData[blobSize + 2 + 2 + i] = 0;
1574  }
1575  }
1576  blobData [1] = ((blobSize + 2 + paddingSize) >> 3) - 1;
1577  blob.AddAtStart (blobSize + 2 + paddingSize);
1578  blob.Begin ().Write (blobData, blobSize + 2 + paddingSize);
1579  destHeader.Deserialize (blob.Begin ());
1580 
1581  packet->AddHeader (destHeader);
1582  break;
1584  // \todo: IPv6 Mobility Header is not supported in ns-3
1585  NS_ABORT_MSG ("IPv6 Mobility Header is not supported in ns-3 yet");
1586  break;
1588  actualHeaderType = Ipv6Header::IPV6_IPV6;
1589  DecompressLowPanIphc (packet, src, dst);
1590  break;
1591  default:
1592  NS_ABORT_MSG ("Trying to decode unknown Extension Header");
1593  break;
1594  }
1595 
1596  NS_LOG_DEBUG ( "Rebuilt packet: " << *packet << " Size " << packet->GetSize () );
1597  return actualHeaderType;
1598 }
1599 
1600 uint32_t
1602 {
1603  NS_LOG_FUNCTION (this << *packet << int(omitChecksum));
1604 
1605  UdpHeader udpHeader;
1606  SixLowPanUdpNhcExtension udpNhcHeader;
1607  uint32_t size = 0;
1608 
1609  NS_ASSERT_MSG (packet->PeekHeader (udpHeader) != 0, "UDP header not found, abort");
1610 
1611  size += packet->RemoveHeader (udpHeader);
1612 
1613  // Set the C field and checksum
1614  udpNhcHeader.SetC (false);
1615  uint16_t checksum = udpHeader.GetChecksum ();
1616  udpNhcHeader.SetChecksum (checksum);
1617 
1618  if (omitChecksum && udpHeader.IsChecksumOk ())
1619  {
1620  udpNhcHeader.SetC (true);
1621  }
1622 
1623  // Set the value of the ports
1624  udpNhcHeader.SetSrcPort (udpHeader.GetSourcePort ());
1625  udpNhcHeader.SetDstPort (udpHeader.GetDestinationPort ());
1626 
1627  //Set the P field
1628  if ( (udpHeader.GetSourcePort () >> 4 ) == 0xf0b && (udpHeader.GetDestinationPort () >> 4 ) == 0xf0b )
1629  {
1631  }
1632  else if ( (udpHeader.GetSourcePort () >> 8 ) == 0xf0 && (udpHeader.GetDestinationPort () >> 8 ) != 0xf0 )
1633  {
1635  }
1636  else if ( (udpHeader.GetSourcePort () >> 8 ) != 0xf0 && (udpHeader.GetDestinationPort () >> 8 ) == 0xf0 )
1637  {
1639  }
1640  else
1641  {
1643  }
1644 
1645  NS_LOG_DEBUG ("UDP_NHC Compression - UDP_NHC header size = " << udpNhcHeader.GetSerializedSize () );
1646  NS_LOG_DEBUG ("UDP_NHC Compression - packet size = " << packet->GetSize () );
1647 
1648  packet->AddHeader (udpNhcHeader);
1649 
1650  NS_LOG_DEBUG ("Packet after UDP_NHC compression: " << *packet);
1651 
1652  return size;
1653 }
1654 
1655 void
1657 {
1658  NS_LOG_FUNCTION (this << *packet);
1659 
1660  UdpHeader udpHeader;
1661  SixLowPanUdpNhcExtension encoding;
1662 
1663  uint32_t ret = packet->RemoveHeader (encoding);
1664  NS_LOG_DEBUG ("removed " << ret << " bytes - pkt is " << *packet);
1665  NS_UNUSED (ret);
1666 
1667  // Set the value of the ports
1668  switch ( encoding.GetPorts () )
1669  {
1670  uint16_t temp;
1672  udpHeader.SetSourcePort (encoding.GetSrcPort ());
1673  udpHeader.SetDestinationPort (encoding.GetDstPort ());
1674  break;
1676  udpHeader.SetSourcePort (encoding.GetSrcPort ());
1677  temp = 0xf0;
1678  temp |= (temp << 8) | encoding.GetDstPort ();
1679  udpHeader.SetDestinationPort (temp);
1680  break;
1682  temp = 0xf0;
1683  temp |= (temp << 8) | encoding.GetSrcPort ();
1684  udpHeader.SetSourcePort (temp);
1685  udpHeader.SetDestinationPort (encoding.GetDstPort ());
1686  break;
1688  temp = 0xf0b;
1689  temp |= (temp << 4) | encoding.GetSrcPort ();
1690  udpHeader.SetSourcePort (temp);
1691  temp = 0xf0b;
1692  temp |= (temp << 4) | encoding.GetDstPort ();
1693  udpHeader.SetDestinationPort (temp);
1694  break;
1695  }
1696 
1697  // Get the C field and checksum
1698  if (Node::ChecksumEnabled ())
1699  {
1700  if ( encoding.GetC () )
1701  {
1702  NS_LOG_LOGIC ("Recalculating UDP Checksum");
1703  udpHeader.EnableChecksums ();
1704  udpHeader.InitializeChecksum (saddr,
1705  daddr,
1707  packet->AddHeader (udpHeader);
1708  }
1709  else
1710  {
1711  NS_LOG_LOGIC ("Forcing UDP Checksum to " << encoding.GetChecksum ());
1712  udpHeader.ForceChecksum (encoding.GetChecksum ());
1713  packet->AddHeader (udpHeader);
1714  NS_LOG_LOGIC ("UDP checksum is ok ? " << udpHeader.IsChecksumOk ());
1715  }
1716  }
1717  else
1718  {
1719  packet->AddHeader (udpHeader);
1720  }
1721 
1722  NS_LOG_DEBUG ( "Rebuilt packet: " << *packet << " Size " << packet->GetSize () );
1723 }
1724 
1726  uint32_t origPacketSize,
1727  uint32_t origHdrSize,
1728  std::list<Ptr<Packet> >& listFragments)
1729 {
1730  NS_LOG_FUNCTION (this << *packet);
1731 
1732  Ptr<Packet> p = packet->Copy ();
1733 
1734  uint16_t offsetData = 0;
1735  uint16_t offset = 0;
1736  uint16_t l2Mtu = m_netDevice->GetMtu ();
1737  uint32_t packetSize = packet->GetSize ();
1738  uint32_t compressedHeaderSize = packetSize - (origPacketSize - origHdrSize);
1739 
1740  uint16_t tag = uint16_t (m_rng->GetValue (0, 65535));
1741  NS_LOG_LOGIC ("random tag " << tag << " - test " << packetSize );
1742 
1743  // first fragment
1744  SixLowPanFrag1 frag1Hdr;
1745  frag1Hdr.SetDatagramTag (tag);
1746 
1747  uint32_t size;
1748  NS_ASSERT_MSG ( l2Mtu > frag1Hdr.GetSerializedSize (),
1749  "6LoWPAN: can not fragment, 6LoWPAN headers are bigger than MTU");
1750 
1751  size = l2Mtu - frag1Hdr.GetSerializedSize () - compressedHeaderSize;
1752  size -= size % 8;
1753  size += compressedHeaderSize;
1754 
1755  frag1Hdr.SetDatagramSize (origPacketSize);
1756 
1757  Ptr<Packet> fragment1 = p->CreateFragment (offsetData, size);
1758  offset += size + origHdrSize - compressedHeaderSize;
1759  offsetData += size;
1760 
1761  fragment1->AddHeader (frag1Hdr);
1762  listFragments.push_back (fragment1);
1763 
1764  bool moreFrag = true;
1765  do
1766  {
1767  SixLowPanFragN fragNHdr;
1768  fragNHdr.SetDatagramTag (tag);
1769  fragNHdr.SetDatagramSize (origPacketSize);
1770  fragNHdr.SetDatagramOffset ((offset) >> 3);
1771 
1772  size = l2Mtu - fragNHdr.GetSerializedSize ();
1773  size -= size % 8;
1774 
1775  if ( (offsetData + size) > packetSize )
1776  {
1777  size = packetSize - offsetData;
1778  moreFrag = false;
1779  }
1780 
1781  NS_LOG_LOGIC ("Fragment creation - " << offset << ", " << offset );
1782  Ptr<Packet> fragment = p->CreateFragment (offsetData, size);
1783  NS_LOG_LOGIC ("Fragment created - " << offset << ", " << fragment->GetSize () );
1784 
1785  offset += size;
1786  offsetData += size;
1787 
1788  fragment->AddHeader (fragNHdr);
1789  listFragments.push_back (fragment);
1790 
1791  }
1792  while (moreFrag);
1793 
1794  return;
1795 }
1796 
1797 bool SixLowPanNetDevice::ProcessFragment (Ptr<Packet>& packet, Address const &src, Address const &dst, bool isFirst)
1798 {
1799  NS_LOG_FUNCTION ( this << *packet );
1800  SixLowPanFrag1 frag1Header;
1801  SixLowPanFragN fragNHeader;
1802  FragmentKey key;
1803  uint16_t packetSize;
1804  key.first = std::pair<Address, Address> (src, dst);
1805 
1806  Ptr<Packet> p = packet->Copy ();
1807  uint16_t offset = 0;
1808 
1809  /* Implementation note:
1810  *
1811  * The fragment offset is relative to the *uncompressed* packet.
1812  * On the other hand, the packet can not be uncompressed correctly without all
1813  * its fragments, as the UDP checksum can not be computed otherwise.
1814  *
1815  * As a consequence we must uncompress the packet twice, and save its first
1816  * fragment for the final one.
1817  */
1818 
1819  if ( isFirst )
1820  {
1821  uint8_t dispatchRawValFrag1 = 0;
1822  SixLowPanDispatch::Dispatch_e dispatchValFrag1;
1823 
1824  p->RemoveHeader (frag1Header);
1825  packetSize = frag1Header.GetDatagramSize ();
1826  p->CopyData (&dispatchRawValFrag1, sizeof(dispatchRawValFrag1));
1827  dispatchValFrag1 = SixLowPanDispatch::GetDispatchType (dispatchRawValFrag1);
1828  NS_LOG_DEBUG ( "Dispatches: " << int(dispatchRawValFrag1) << " - " << int(dispatchValFrag1) );
1829  NS_LOG_DEBUG ( "Packet: " << *p );
1830 
1831  switch ( dispatchValFrag1 )
1832  {
1834  {
1835  SixLowPanIpv6 uncompressedHdr;
1836  p->RemoveHeader(uncompressedHdr);
1837  }
1838  break;
1840  DecompressLowPanHc1 (p, src, dst);
1841  break;
1843  DecompressLowPanIphc (p, src, dst);
1844  break;
1845  default:
1846  NS_FATAL_ERROR ("Unsupported 6LoWPAN encoding, exiting.");
1847  break;
1848  }
1849 
1850  key.second = std::pair<uint16_t, uint16_t> (frag1Header.GetDatagramSize (), frag1Header.GetDatagramTag ());
1851  }
1852  else
1853  {
1854  p->RemoveHeader (fragNHeader);
1855  packetSize = fragNHeader.GetDatagramSize ();
1856  offset = fragNHeader.GetDatagramOffset () << 3;
1857  key.second = std::pair<uint16_t, uint16_t> (fragNHeader.GetDatagramSize (), fragNHeader.GetDatagramTag ());
1858  }
1859 
1860  Ptr<Fragments> fragments;
1861 
1862  MapFragments_t::iterator it = m_fragments.find (key);
1863  if (it == m_fragments.end ())
1864  {
1865  // erase the oldest packet.
1867  {
1868  MapFragmentsTimers_t::iterator iter;
1869  MapFragmentsTimers_t::iterator iterFound = m_fragmentsTimers.begin ();
1870  for ( iter = m_fragmentsTimers.begin (); iter != m_fragmentsTimers.end (); iter++)
1871  {
1872  if ( iter->second.GetTs () < iterFound->second.GetTs () )
1873  {
1874  iterFound = iter;
1875  }
1876  }
1877  FragmentKey oldestKey = iterFound->first;
1878 
1879  std::list< Ptr<Packet> > storedFragments = m_fragments[oldestKey]->GetFraments ();
1880  for (std::list< Ptr<Packet> >::iterator fragIter = storedFragments.begin ();
1881  fragIter != storedFragments.end (); fragIter++)
1882  {
1884  }
1885 
1886  m_fragmentsTimers[oldestKey].Cancel ();
1887  m_fragmentsTimers.erase (oldestKey);
1888  m_fragments[oldestKey] = 0;
1889  m_fragments.erase (oldestKey);
1890 
1891  }
1892  fragments = Create<Fragments> ();
1893  fragments->SetPacketSize (packetSize);
1894  m_fragments.insert (std::make_pair (key, fragments));
1895  uint32_t ifIndex = GetIfIndex ();
1898  key, ifIndex);
1899  }
1900  else
1901  {
1902  fragments = it->second;
1903  }
1904 
1905  fragments->AddFragment (p, offset);
1906 
1907  // add the very first fragment so we can correctly decode the packet once is rebuilt.
1908  // this is needed because otherwise the UDP header length and checksum can not be calculated.
1909  if ( isFirst )
1910  {
1911  fragments->AddFirstFragment (packet);
1912  }
1913 
1914  if ( fragments->IsEntire () )
1915  {
1916  packet = fragments->GetPacket ();
1917  NS_LOG_LOGIC ("Reconstructed packet: " << *packet);
1918 
1919  SixLowPanFrag1 frag1Header;
1920  packet->RemoveHeader (frag1Header);
1921 
1922  NS_LOG_LOGIC ("Rebuilt packet. Size " << packet->GetSize () << " - " << *packet);
1923  fragments = 0;
1924  m_fragments.erase (key);
1925  if (m_fragmentsTimers[key].IsRunning ())
1926  {
1927  NS_LOG_LOGIC ("Stopping 6LoWPAN WaitFragmentsTimer at " << Simulator::Now ().GetSeconds () << " due to complete packet");
1928  m_fragmentsTimers[key].Cancel ();
1929  }
1930  m_fragmentsTimers.erase (key);
1931  return true;
1932  }
1933 
1934  return false;
1935 }
1936 
1938 {
1939  NS_LOG_FUNCTION (this);
1940  m_packetSize = 0;
1941 }
1942 
1944 {
1945  NS_LOG_FUNCTION (this);
1946 }
1947 
1948 void SixLowPanNetDevice::Fragments::AddFragment (Ptr<Packet> fragment, uint16_t fragmentOffset)
1949 {
1950  NS_LOG_FUNCTION (this << fragmentOffset << *fragment);
1951 
1952  std::list<std::pair<Ptr<Packet>, uint16_t> >::iterator it;
1953  bool duplicate = false;
1954 
1955  for (it = m_fragments.begin (); it != m_fragments.end (); it++)
1956  {
1957  if (it->second > fragmentOffset)
1958  {
1959  break;
1960  }
1961  if (it->second == fragmentOffset)
1962  {
1963  duplicate = true;
1964  NS_ASSERT_MSG (fragment->GetSize () == it->first->GetSize (), "Duplicate fragment size differs. Aborting.");
1965  break;
1966  }
1967  }
1968  if (!duplicate)
1969  {
1970  m_fragments.insert (it, std::make_pair (fragment, fragmentOffset));
1971  }
1972 }
1973 
1975 {
1976  NS_LOG_FUNCTION (this << *fragment);
1977 
1978  m_firstFragment = fragment;
1979 }
1980 
1982 {
1983  NS_LOG_FUNCTION (this);
1984 
1985  bool ret = m_fragments.size () > 0;
1986  uint16_t lastEndOffset = 0;
1987 
1988  if (ret)
1989  {
1990  for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
1991  {
1992  // overlapping fragments should not exist
1993  NS_LOG_LOGIC ("Checking overlaps " << lastEndOffset << " - " << it->second );
1994 
1995  if (lastEndOffset < it->second)
1996  {
1997  ret = false;
1998  break;
1999  }
2000  // fragments might overlap in strange ways
2001  uint16_t fragmentEnd = it->first->GetSize () + it->second;
2002  lastEndOffset = std::max ( lastEndOffset, fragmentEnd );
2003  }
2004  }
2005 
2006  if ( ret && (lastEndOffset == m_packetSize))
2007  {
2008  return true;
2009  }
2010  return false;
2011 }
2012 
2014 {
2015  NS_LOG_FUNCTION (this);
2016 
2017  std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin ();
2018 
2019  Ptr<Packet> p = Create<Packet> ();
2020  uint16_t lastEndOffset = 0;
2021 
2022  p->AddAtEnd (m_firstFragment);
2023  it = m_fragments.begin ();
2024  lastEndOffset = it->first->GetSize ();
2025 
2026  for ( it++; it != m_fragments.end (); it++)
2027  {
2028  if ( lastEndOffset > it->second )
2029  {
2030  NS_ABORT_MSG ("Overlapping fragments found, forbidden condition");
2031  }
2032  else
2033  {
2034  NS_LOG_LOGIC ("Adding: " << *(it->first) );
2035  p->AddAtEnd (it->first);
2036  }
2037  lastEndOffset += it->first->GetSize ();
2038  }
2039 
2040  return p;
2041 }
2042 
2044 {
2045  NS_LOG_FUNCTION (this << packetSize);
2046  m_packetSize = packetSize;
2047 }
2048 
2049 std::list< Ptr<Packet> > SixLowPanNetDevice::Fragments::GetFraments () const
2050 {
2051  std::list< Ptr<Packet> > fragments;
2052  std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator iter;
2053  for ( iter = m_fragments.begin (); iter != m_fragments.end (); iter ++)
2054  {
2055  fragments.push_back (iter->first);
2056  }
2057  return fragments;
2058 }
2059 
2061 {
2062  NS_LOG_FUNCTION (this);
2063 
2064  MapFragments_t::iterator it = m_fragments.find (key);
2065  std::list< Ptr<Packet> > storedFragments = it->second->GetFraments ();
2066  for (std::list< Ptr<Packet> >::iterator fragIter = storedFragments.begin ();
2067  fragIter != storedFragments.end (); fragIter++)
2068  {
2070  }
2071  // clear the buffers
2072  it->second = 0;
2073 
2074  m_fragments.erase (key);
2075  m_fragmentsTimers.erase (key);
2076 }
2077 
2079 {
2080  Ipv6Address ipv6Addr = Ipv6Address::GetAny ();
2081 
2083  {
2085  }
2086  else
2087  {
2088  if (Mac64Address::IsMatchingType (addr))
2089  {
2091  }
2092  else if (Mac16Address::IsMatchingType (addr))
2093  {
2095  }
2096  }
2097  if (ipv6Addr.IsAny ())
2098  {
2099  NS_ABORT_MSG ("Unknown address type");
2100  }
2101  return ipv6Addr;
2102 }
2103 
2105 {
2106  Ipv6Address ipv6Addr = Ipv6Address::GetAny ();
2107 
2109  {
2111  }
2112  else
2113  {
2114  if (Mac64Address::IsMatchingType (addr))
2115  {
2117  }
2118  else if (Mac16Address::IsMatchingType (addr))
2119  {
2121  }
2122  }
2123  if (ipv6Addr.IsAny ())
2124  {
2125  NS_ABORT_MSG ("Unknown address type");
2126  }
2127  return ipv6Addr;
2128 }
2129 
2130 }
2131 
2132 // 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:266
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:144
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 AddAtStart(uint32_t start)
Definition: buffer.cc:309
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.
Definition: second.py:1
#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 uncompressed header - see RFC 4944.
void RemoveAtStart(uint32_t start)
Definition: buffer.cc:441
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:455
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:269
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:366
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:1258
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:276
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:786
#define NS_UNUSED(x)
Mark a local variable as unused.
Definition: unused.h:36
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.
uint16_t m_fragmentReassemblyListSize
How many packets can be rebuilt at the same time.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:145
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:339
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.
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 -> expiration 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:446
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:311
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 Source 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.
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1216
void SetHc2HeaderPresent(bool hc2HeaderPresent)
Set the next header a HC2 compressed header.
AttributeValue implementation for Time.
Definition: nstime.h:957
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:705
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:1480
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:1063
virtual void SetPromiscReceiveCallback(NetDevice::PromiscReceiveCallback cb)
#define list
void SetSrcPort(uint16_t port)
Set the Source 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:241
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:276
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)
Get the next random value, as a double in 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)
Performs a packet fragmentation.
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:958
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:1057
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 RFC 4944 and RFC 6282
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:220
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:90
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:107
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:895
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:953
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:354
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.
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.
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< 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:58
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)
Set the parent TypeId.
Definition: type-id.cc:826
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:255
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.