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 (origPacketSize > m_compressionThreshold)
441  {
442  if (m_useIphc)
443  {
444  NS_LOG_LOGIC ("Compressing packet using IPHC");
445  origHdrSize += CompressLowPanIphc (packet, m_netDevice->GetAddress (), dest);
446  }
447  else
448  {
449  NS_LOG_LOGIC ("Compressing packet using HC1");
450  origHdrSize += CompressLowPanHc1 (packet, m_netDevice->GetAddress (), dest);
451  }
452  }
453  else
454  {
455  NS_LOG_LOGIC ("Compressed packet too short, using uncompressed one");
456  packet = origPacket;
457  SixLowPanIpv6 ipv6UncompressedHdr;
458  packet->AddHeader (ipv6UncompressedHdr);
459  }
460 
461  if ( packet->GetSize () > m_netDevice->GetMtu () )
462  {
463  NS_LOG_LOGIC ("Fragmentation: Packet size " << packet->GetSize () << " - Mtu " << m_netDevice->GetMtu () );
464  // fragment
465  std::list<Ptr<Packet> > fragmentList;
466  DoFragmentation (packet, origPacketSize, origHdrSize, fragmentList);
467  std::list<Ptr<Packet> >::iterator it;
468  bool success = true;
469  for ( it = fragmentList.begin (); it != fragmentList.end (); it++ )
470  {
471  NS_LOG_DEBUG ( "SixLowPanNetDevice::Send (Fragment) " << **it );
473  if (doSendFrom)
474  {
475  success &= m_netDevice->SendFrom (*it, src, dest, protocolNumber);
476  }
477  else
478  {
479  success &= m_netDevice->Send (*it, dest, protocolNumber);
480  }
481  }
482  ret = success;
483  }
484  else
485  {
487  if (doSendFrom)
488  {
489  NS_LOG_DEBUG ( "SixLowPanNetDevice::SendFrom " << m_node->GetId () << " " << *packet );
490  ret = m_netDevice->SendFrom (packet, src, dest, protocolNumber);
491  }
492  else
493  {
494  NS_LOG_DEBUG ( "SixLowPanNetDevice::Send " << m_node->GetId () << " " << *packet );
495  ret = m_netDevice->Send (packet, dest, protocolNumber);
496  }
497  }
498 
499  return ret;
500 }
501 
503 {
504  NS_LOG_FUNCTION (this);
505  return m_node;
506 }
507 
509 {
510  NS_LOG_FUNCTION (this << node);
511  m_node = node;
512 }
513 
515 {
516  NS_LOG_FUNCTION (this);
517  NS_ASSERT_MSG ( m_netDevice != 0, "Sixlowpan: can't find any lower-layer protocol " << m_netDevice );
518 
519  return m_netDevice->NeedsArp ();
520 }
521 
523 {
524  NS_LOG_FUNCTION (this << &cb);
525  m_rxCallback = cb;
526 }
527 
529 {
530  NS_LOG_FUNCTION (this << &cb);
531  m_promiscRxCallback = cb;
532 }
533 
535 {
536  NS_LOG_FUNCTION (this);
537  return true;
538 }
539 
540 uint32_t
542 {
543  NS_LOG_FUNCTION (this << *packet << src << dst);
544 
545  Ipv6Header ipHeader;
546  SixLowPanHc1 hc1Header;
547  uint32_t size = 0;
548 
549  if ( packet->PeekHeader (ipHeader) != 0 )
550  {
551  packet->RemoveHeader (ipHeader);
552  size += ipHeader.GetSerializedSize ();
553 
554  hc1Header.SetHopLimit (ipHeader.GetHopLimit ());
555 
556  uint8_t bufOne[16];
557  uint8_t bufTwo[16];
558  Ipv6Address srcAddr = ipHeader.GetSourceAddress ();
559  srcAddr.GetBytes (bufOne);
560  Ipv6Address mySrcAddr = MakeLinkLocalAddressFromMac (src);
561 
562  NS_LOG_LOGIC ("Checking source compression: " << mySrcAddr << " - " << srcAddr );
563 
564  mySrcAddr.GetBytes (bufTwo);
565  bool isSrcSrc = (memcmp (bufOne + 8, bufTwo + 8, 8) == 0);
566 
567  if (srcAddr.IsLinkLocal () && isSrcSrc )
568  {
570  }
571  else if (srcAddr.IsLinkLocal () )
572  {
574  hc1Header.SetSrcInterface (bufOne + 8);
575  }
576  else if ( isSrcSrc )
577  {
579  hc1Header.SetSrcPrefix (bufOne);
580  }
581  else
582  {
584  hc1Header.SetSrcInterface (bufOne + 8);
585  hc1Header.SetSrcPrefix (bufOne);
586  }
587 
588  Ipv6Address dstAddr = ipHeader.GetDestinationAddress ();
589  dstAddr.GetBytes (bufOne);
590  Ipv6Address myDstAddr = MakeLinkLocalAddressFromMac (dst);
591 
592  NS_LOG_LOGIC ("Checking destination compression: " << myDstAddr << " - " << dstAddr );
593 
594  myDstAddr.GetBytes (bufTwo);
595  bool isDstDst = (memcmp (bufOne + 8, bufTwo + 8, 8) == 0);
596 
597  if (dstAddr.IsLinkLocal () && isDstDst )
598  {
600  }
601  else if (dstAddr.IsLinkLocal () )
602  {
604  hc1Header.SetDstInterface (bufOne + 8);
605  }
606  else if ( isDstDst )
607  {
609  hc1Header.SetDstPrefix (bufOne);
610  }
611  else
612  {
614  hc1Header.SetDstInterface (bufOne + 8);
615  hc1Header.SetDstPrefix (bufOne);
616  }
617 
618  if ( (ipHeader.GetFlowLabel () == 0) && (ipHeader.GetTrafficClass () == 0) )
619  {
620  hc1Header.SetTcflCompression (true);
621  }
622  else
623  {
624  hc1Header.SetTcflCompression (false);
625  hc1Header.SetTrafficClass (ipHeader.GetTrafficClass ());
626  hc1Header.SetFlowLabel (ipHeader.GetFlowLabel ());
627  }
628 
629  uint8_t nextHeader = ipHeader.GetNextHeader ();
630  hc1Header.SetNextHeader (nextHeader);
631 
632  // \todo implement HC2 compression
633  hc1Header.SetHc2HeaderPresent (false);
634 
635  NS_LOG_DEBUG ("HC1 Compression - HC1 header size = " << hc1Header.GetSerializedSize () );
636  NS_LOG_DEBUG ("HC1 Compression - packet size = " << packet->GetSize () );
637 
638  packet->AddHeader (hc1Header);
639 
640  return size;
641  }
642 
643  return 0;
644 }
645 
646 void
648 {
649  NS_LOG_FUNCTION (this << *packet << src << dst);
650 
651  Ipv6Header ipHeader;
652  SixLowPanHc1 encoding;
653 
654  uint32_t ret = packet->RemoveHeader (encoding);
655  NS_LOG_DEBUG ("removed " << ret << " bytes - pkt is " << *packet);
656  NS_UNUSED (ret);
657 
658  ipHeader.SetHopLimit (encoding.GetHopLimit ());
659 
660  switch (encoding.GetSrcCompression ())
661  {
662  const uint8_t* interface;
663  const uint8_t* prefix;
664  uint8_t address[16];
665 
667  prefix = encoding.GetSrcPrefix ();
668  interface = encoding.GetSrcInterface ();
669  for (int j = 0; j < 8; j++)
670  {
671  address[j + 8] = interface[j];
672  address[j] = prefix[j];
673  }
674  ipHeader.SetSourceAddress ( Ipv6Address (address) );
675  break;
677  prefix = encoding.GetSrcPrefix ();
678  for (int j = 0; j < 8; j++)
679  {
680  address[j + 8] = 0;
681  address[j] = prefix[j];
682  }
683  ipHeader.SetSourceAddress ( MakeGlobalAddressFromMac (src, Ipv6Address (address)));
684  break;
686  interface = encoding.GetSrcInterface ();
687  address[0] = 0xfe;
688  address[1] = 0x80;
689  for (int j = 0; j < 8; j++)
690  {
691  address[j + 8] = interface[j];
692  }
693  ipHeader.SetSourceAddress ( Ipv6Address (address) );
694  break;
697  break;
698  }
699 
700  switch (encoding.GetDstCompression ())
701  {
702  const uint8_t* interface;
703  const uint8_t* prefix;
704  uint8_t address[16];
705 
707  prefix = encoding.GetDstPrefix ();
708  interface = encoding.GetDstInterface ();
709  for (int j = 0; j < 8; j++)
710  {
711  address[j + 8] = interface[j];
712  address[j] = prefix[j];
713  }
714  ipHeader.SetDestinationAddress ( Ipv6Address (address) );
715  break;
717  prefix = encoding.GetDstPrefix ();
718  for (int j = 0; j < 8; j++)
719  {
720  address[j + 8] = 0;
721  address[j] = prefix[j];
722  }
723  ipHeader.SetDestinationAddress ( MakeGlobalAddressFromMac (dst, Ipv6Address (address)));
724  break;
726  interface = encoding.GetDstInterface ();
727  address[0] = 0xfe;
728  address[1] = 0x80;
729  for (int j = 0; j < 8; j++)
730  {
731  address[j + 8] = interface[j];
732  }
733  ipHeader.SetDestinationAddress ( Ipv6Address (address) );
734  break;
737  break;
738  }
739 
740  if ( !encoding.IsTcflCompression () )
741  {
742  ipHeader.SetFlowLabel (encoding.GetFlowLabel ());
743  ipHeader.SetTrafficClass (encoding.GetTrafficClass ());
744  }
745  else
746  {
747  ipHeader.SetFlowLabel (0);
748  ipHeader.SetTrafficClass (0);
749  }
750 
751  ipHeader.SetNextHeader (encoding.GetNextHeader ());
752 
753  ipHeader.SetPayloadLength (packet->GetSize ());
754 
755  NS_ASSERT_MSG (encoding.IsHc2HeaderPresent () == false,
756  "6LoWPAN: error in decompressing HC1 encoding, unsupported L4 compressed header present.");
757 
758  packet->AddHeader (ipHeader);
759 
760  NS_LOG_DEBUG ( "Rebuilt packet: " << *packet << " Size " << packet->GetSize () );
761 }
762 
763 uint32_t
765 {
766  NS_LOG_FUNCTION (this << *packet << src << dst);
767 
768  Ipv6Header ipHeader;
769  SixLowPanIphc iphcHeader;
770  uint32_t size = 0;
771 
772 
773  if ( packet->PeekHeader (ipHeader) != 0 )
774  {
775  packet->RemoveHeader (ipHeader);
776  size += ipHeader.GetSerializedSize ();
777 
778  // Set the TF field
779  if ( (ipHeader.GetFlowLabel () == 0) && (ipHeader.GetTrafficClass () == 0) )
780  {
781  iphcHeader.SetTf (SixLowPanIphc::TF_ELIDED);
782  }
783  else if ( (ipHeader.GetFlowLabel () != 0) && (ipHeader.GetTrafficClass () != 0) )
784  {
785  iphcHeader.SetTf (SixLowPanIphc::TF_FULL);
786  iphcHeader.SetEcn ( (ipHeader.GetTrafficClass () & 0xC0) >> 6);
787  iphcHeader.SetDscp ( ipHeader.GetTrafficClass () & 0x3F );
788  iphcHeader.SetFlowLabel (ipHeader.GetFlowLabel ());
789  }
790  else if ( (ipHeader.GetFlowLabel () == 0) && (ipHeader.GetTrafficClass () != 0) )
791  {
792  iphcHeader.SetTf (SixLowPanIphc::TF_FL_ELIDED);
793  iphcHeader.SetEcn ( (ipHeader.GetTrafficClass () & 0xC0) >> 6);
794  iphcHeader.SetDscp ( ipHeader.GetTrafficClass () & 0x3F );
795  }
796  else
797  {
799  iphcHeader.SetEcn ( (ipHeader.GetTrafficClass () & 0xC0) >> 6);
800  iphcHeader.SetFlowLabel (ipHeader.GetFlowLabel ());
801  }
802 
803  // Set the NH field and NextHeader
804 
805  uint8_t nextHeader = ipHeader.GetNextHeader ();
806  if (CanCompressLowPanNhc (nextHeader))
807  {
808  if (nextHeader == Ipv6Header::IPV6_UDP)
809  {
810  iphcHeader.SetNh (true);
811  size += CompressLowPanUdpNhc (packet, m_omitUdpChecksum);
812  }
813  else if (nextHeader == Ipv6Header::IPV6_IPV6)
814  {
815  iphcHeader.SetNh (true);
816  size += CompressLowPanIphc (packet, src, dst);
817  }
818  else
819  {
820  uint32_t sizeNhc = CompressLowPanNhc (packet, nextHeader, src, dst);
821  // the compression might fail due to Extension header size.
822  if (sizeNhc)
823  {
824  iphcHeader.SetNh (true);
825  size += sizeNhc;
826  }
827  else
828  {
829  iphcHeader.SetNh (false);
830  iphcHeader.SetNextHeader (nextHeader);
831  }
832  }
833  }
834  else
835  {
836  iphcHeader.SetNh (false);
837  iphcHeader.SetNextHeader (nextHeader);
838  }
839 
840 
841  // Set the HLIM field
842  if (ipHeader.GetHopLimit () == 1)
843  {
845  }
846  else if (ipHeader.GetHopLimit () == 0x40)
847  {
849  }
850  else if (ipHeader.GetHopLimit () == 0xFF)
851  {
853  }
854  else
855  {
856  iphcHeader.SetHlim (SixLowPanIphc::HLIM_INLINE);
857  // Set the HopLimit
858  iphcHeader.SetHopLimit (ipHeader.GetHopLimit ());
859  }
860 
861  // \todo Add the check of CID if there is context-based compression
862  // Set the CID field
863  iphcHeader.SetCid (false);
864 
865  // \todo Add the check of SAC if there is context-based compression
866  // Set the SAC field
867  iphcHeader.SetSac (false);
868 
869  uint8_t addressBuf[16];
870  uint8_t unicastAddrCheckerBuf[16];
871  Ipv6Address srcAddr = ipHeader.GetSourceAddress ();
872  srcAddr.GetBytes (addressBuf);
873 
874  Ipv6Address checker = Ipv6Address ("fe80:0000:0000:0000:0000:00ff:fe00:1");
875  checker.GetBytes (unicastAddrCheckerBuf);
876 
877  // \todo Add the check of SAC if there is context-based compression
878  // Set the Source Address
879  iphcHeader.SetSrcAddress (srcAddr);
880 
881  Ipv6Address mySrcAddr = MakeLinkLocalAddressFromMac (src);
882  NS_LOG_LOGIC ("Checking source compression: " << mySrcAddr << " - " << srcAddr );
883 
884  if ( mySrcAddr == srcAddr )
885  {
886  iphcHeader.SetSam (SixLowPanIphc::HC_COMPR_0);
887  }
888  else if (memcmp (addressBuf, unicastAddrCheckerBuf, 14) == 0)
889  {
890  iphcHeader.SetSam (SixLowPanIphc::HC_COMPR_16);
891  }
892  else if ( srcAddr.IsLinkLocal () )
893  {
894  iphcHeader.SetSam (SixLowPanIphc::HC_COMPR_64);
895  }
896  else
897  {
898  iphcHeader.SetSam (SixLowPanIphc::HC_INLINE);
899  }
900 
901  // Set the M field
902  if (ipHeader.GetDestinationAddress ().IsMulticast ())
903  {
904  iphcHeader.SetM (true);
905  }
906  else
907  {
908  iphcHeader.SetM (false);
909  }
910 
911  // \todo Add the check of DAC if there is context-based compression
912  // Set the DAC field
913  iphcHeader.SetDac (false);
914 
915  Ipv6Address dstAddr = ipHeader.GetDestinationAddress ();
916  dstAddr.GetBytes (addressBuf);
917 
918  // \todo Add the check of DAC if there is context-based compression
919  // Set the Destination Address
920  iphcHeader.SetDstAddress (dstAddr);
921 
922  Ipv6Address myDstAddr = MakeLinkLocalAddressFromMac (dst);
923  NS_LOG_LOGIC ("Checking destination compression: " << myDstAddr << " - " << dstAddr );
924 
925  if ( !iphcHeader.GetM () )
926  // Unicast address
927  {
928  if ( myDstAddr == dstAddr )
929  {
930  iphcHeader.SetDam (SixLowPanIphc::HC_COMPR_0);
931  }
932  else if (memcmp (addressBuf, unicastAddrCheckerBuf, 14) == 0)
933  {
934  iphcHeader.SetDam (SixLowPanIphc::HC_COMPR_16);
935  }
936  else if ( dstAddr.IsLinkLocal () )
937  {
938  iphcHeader.SetDam (SixLowPanIphc::HC_COMPR_64);
939  }
940  else
941  {
942  iphcHeader.SetDam (SixLowPanIphc::HC_INLINE);
943  }
944  }
945  else
946  {
947  // Multicast address
948  uint8_t multicastAddrCheckerBuf[16];
949  Ipv6Address multicastCheckAddress = Ipv6Address ("ff02::1");
950  multicastCheckAddress.GetBytes (multicastAddrCheckerBuf);
951 
952  // The address takes the form ff02::00XX.
953  if ( memcmp (addressBuf, multicastAddrCheckerBuf, 15) == 0 )
954  {
955  iphcHeader.SetDam (SixLowPanIphc::HC_COMPR_0);
956  }
957  // The address takes the form ffXX::00XX:XXXX.
958  // ffXX:0000:0000:0000:0000:0000:00XX:XXXX.
959  else if ( (addressBuf[0] == multicastAddrCheckerBuf[0])
960  && (memcmp (addressBuf + 2, multicastAddrCheckerBuf + 2, 11) == 0) )
961  {
962  iphcHeader.SetDam (SixLowPanIphc::HC_COMPR_16);
963  }
964  // The address takes the form ffXX::00XX:XXXX:XXXX.
965  // ffXX:0000:0000:0000:0000:00XX:XXXX:XXXX.
966  else if ( (addressBuf[0] == multicastAddrCheckerBuf[0])
967  && (memcmp (addressBuf + 2, multicastAddrCheckerBuf + 2, 9) == 0) )
968  {
969  iphcHeader.SetDam (SixLowPanIphc::HC_COMPR_64);
970  }
971  else
972  {
973  iphcHeader.SetDam (SixLowPanIphc::HC_INLINE);
974  }
975  }
976 
977  NS_LOG_DEBUG ("IPHC Compression - IPHC header size = " << iphcHeader.GetSerializedSize () );
978  NS_LOG_DEBUG ("IPHC Compression - packet size = " << packet->GetSize () );
979 
980  packet->AddHeader (iphcHeader);
981 
982  NS_LOG_DEBUG ("Packet after IPHC compression: " << *packet);
983 
984  return size;
985  }
986 
987  return 0;
988 }
989 
990 bool
992 {
993  bool ret = false;
994 
995  switch (nextHeader)
996  {
1001  case Ipv6Header::IPV6_IPV6:
1002  ret = true;
1003  break;
1005  default:
1006  ret = false;
1007  }
1008  return ret;
1009 }
1010 
1011 void
1013 {
1014  NS_LOG_FUNCTION (this << *packet << src << dst);
1015 
1016  Ipv6Header ipHeader;
1017  SixLowPanIphc encoding;
1018 
1019  uint32_t ret = packet->RemoveHeader (encoding);
1020  NS_LOG_DEBUG ("removed " << ret << " bytes - pkt is " << *packet);
1021  NS_UNUSED (ret);
1022 
1023  // Hop Limit
1024  ipHeader.SetHopLimit (encoding.GetHopLimit ());
1025 
1026  // Source address
1027  if ( encoding.GetSac () )
1028  {
1029  if ( encoding.GetSam () == SixLowPanIphc::HC_INLINE )
1030  {
1031  ipHeader.SetSourceAddress ( Ipv6Address::GetAny () );
1032  }
1033  else
1034  {
1035  NS_ABORT_MSG ("SAC option not yet implemented");
1036  }
1037  }
1038  else
1039  {
1040  if ( encoding.GetSam () == SixLowPanIphc::HC_COMPR_0 )
1041  {
1043  }
1044  else
1045  {
1046  ipHeader.SetSourceAddress ( encoding.GetSrcAddress () );
1047  }
1048  }
1049  // Destination address
1050  if ( encoding.GetDac () )
1051  {
1052  if ((encoding.GetDam () == SixLowPanIphc::HC_INLINE && !encoding.GetM ())
1053  || (encoding.GetDam () == SixLowPanIphc::HC_COMPR_64 && encoding.GetM ())
1054  || (encoding.GetDam () == SixLowPanIphc::HC_COMPR_16 && encoding.GetM ())
1055  || (encoding.GetDam () == SixLowPanIphc::HC_COMPR_0 && encoding.GetM ()) )
1056  {
1057  NS_ABORT_MSG ("Reserved code found");
1058  }
1059  else
1060  {
1061  NS_ABORT_MSG ("DAC option not yet implemented");
1062  }
1063  }
1064  else
1065  {
1066  if ( !encoding.GetM () && encoding.GetDam () == SixLowPanIphc::HC_COMPR_0 )
1067  {
1069  }
1070  else
1071  {
1072  ipHeader.SetDestinationAddress ( encoding.GetDstAddress () );
1073  }
1074  }
1075 
1076  // Traffic class and Flow Label
1077  uint8_t traf = 0x00;
1078  switch (encoding.GetTf ())
1079  {
1081  traf |= encoding.GetEcn ();
1082  traf = ( traf << 6 ) | encoding.GetDscp ();
1083  ipHeader.SetTrafficClass (traf);
1084  ipHeader.SetFlowLabel ( encoding.GetFlowLabel () & 0xfff ); //Add 4-bit pad
1085  break;
1087  traf |= encoding.GetEcn ();
1088  traf <<= 2; // Add 2-bit pad
1089  ipHeader.SetTrafficClass (traf);
1090  ipHeader.SetFlowLabel (encoding.GetFlowLabel ());
1091  break;
1093  traf |= encoding.GetEcn ();
1094  traf = ( traf << 6 ) | encoding.GetDscp ();
1095  ipHeader.SetTrafficClass (traf);
1096  ipHeader.SetFlowLabel (0);
1097  break;
1099  ipHeader.SetFlowLabel (0);
1100  ipHeader.SetTrafficClass (0);
1101  break;
1102  }
1103 
1104  if ( encoding.GetNh () )
1105  {
1106  // Next Header
1107  uint8_t dispatchRawVal = 0;
1109 
1110  packet->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
1111  dispatchVal = SixLowPanDispatch::GetNhcDispatchType (dispatchRawVal);
1112 
1113  if (dispatchVal == SixLowPanDispatch::LOWPAN_UDPNHC)
1114  {
1116  DecompressLowPanUdpNhc (packet, ipHeader.GetSourceAddress (), ipHeader.GetDestinationAddress ());
1117  }
1118  else
1119  {
1120  ipHeader.SetNextHeader (DecompressLowPanNhc (packet, src, dst, ipHeader.GetSourceAddress (), ipHeader.GetDestinationAddress ()));
1121  }
1122  }
1123  else
1124  {
1125  ipHeader.SetNextHeader (encoding.GetNextHeader ());
1126  }
1127 
1128  ipHeader.SetPayloadLength (packet->GetSize ());
1129 
1130  packet->AddHeader (ipHeader);
1131 
1132  NS_LOG_DEBUG ( "Rebuilt packet: " << *packet << " Size " << packet->GetSize () );
1133 
1134 }
1135 
1136 uint32_t
1137 SixLowPanNetDevice::CompressLowPanNhc (Ptr<Packet> packet, uint8_t headerType, Address const &src, Address const &dst)
1138 {
1139  NS_LOG_FUNCTION (this << *packet << int(headerType));
1140 
1141  SixLowPanNhcExtension nhcHeader;
1142  uint32_t size = 0;
1143  Buffer blob;
1144 
1145  if (headerType == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
1146  {
1147  Ipv6ExtensionHopByHopHeader hopHeader;
1148  packet->PeekHeader (hopHeader);
1149  if (hopHeader.GetLength () >= 0xff)
1150  {
1151  NS_LOG_DEBUG ("LOWPAN_NHC MUST NOT be used to encode IPv6 Extension Headers "
1152  "that have more than 255 octets following the Length field after compression. "
1153  "Packet uncompressed.");
1154  return 0;
1155  }
1156 
1157  size += packet->RemoveHeader (hopHeader);
1159 
1160  // recursively compress other headers
1161  uint8_t nextHeader = hopHeader.GetNextHeader ();
1162  if (CanCompressLowPanNhc (nextHeader))
1163  {
1164  if (nextHeader == Ipv6Header::IPV6_UDP)
1165  {
1166  nhcHeader.SetNh (true);
1167  size += CompressLowPanUdpNhc (packet, m_omitUdpChecksum);
1168  }
1169  else if (nextHeader == Ipv6Header::IPV6_IPV6)
1170  {
1171  nhcHeader.SetNh (true);
1172  size += CompressLowPanIphc (packet, src, dst);
1173  }
1174  else
1175  {
1176  uint32_t sizeNhc = CompressLowPanNhc (packet, nextHeader, src, dst);
1177  // the compression might fail due to Extension header size.
1178  if (sizeNhc)
1179  {
1180  nhcHeader.SetNh (true);
1181  size += sizeNhc;
1182  }
1183  else
1184  {
1185  nhcHeader.SetNh (false);
1186  nhcHeader.SetNextHeader (nextHeader);
1187  }
1188  }
1189  }
1190  else
1191  {
1192  nhcHeader.SetNh (false);
1193  nhcHeader.SetNextHeader (nextHeader);
1194  }
1195 
1196  uint32_t blobSize = hopHeader.GetSerializedSize ();
1197  blob.AddAtStart (blobSize);
1198  hopHeader.Serialize (blob.Begin ());
1199  blob.RemoveAtStart (2);
1200  blobSize = blob.GetSize ();
1201  nhcHeader.SetBlob (blob.PeekData (), blobSize);
1202  }
1203  else if (headerType == Ipv6Header::IPV6_EXT_ROUTING)
1204  {
1205  Ipv6ExtensionRoutingHeader routingHeader;
1206  packet->PeekHeader (routingHeader);
1207  if (routingHeader.GetLength () >= 0xff)
1208  {
1209  NS_LOG_DEBUG ("LOWPAN_NHC MUST NOT be used to encode IPv6 Extension Headers "
1210  "that have more than 255 octets following the Length field after compression. "
1211  "Packet uncompressed.");
1212  return 0;
1213  }
1214 
1215  size += packet->RemoveHeader (routingHeader);
1217 
1218  // recursively compress other headers
1219  uint8_t nextHeader = routingHeader.GetNextHeader ();
1220  if (CanCompressLowPanNhc (nextHeader))
1221  {
1222  if (nextHeader == Ipv6Header::IPV6_UDP)
1223  {
1224  nhcHeader.SetNh (true);
1225  size += CompressLowPanUdpNhc (packet, m_omitUdpChecksum);
1226  }
1227  else if (nextHeader == Ipv6Header::IPV6_IPV6)
1228  {
1229  nhcHeader.SetNh (true);
1230  size += CompressLowPanIphc (packet, src, dst);
1231  }
1232  else
1233  {
1234  uint32_t sizeNhc = CompressLowPanNhc (packet, nextHeader, src, dst);
1235  // the compression might fail due to Extension header size.
1236  if (sizeNhc)
1237  {
1238  nhcHeader.SetNh (true);
1239  size += sizeNhc;
1240  }
1241  else
1242  {
1243  nhcHeader.SetNh (false);
1244  nhcHeader.SetNextHeader (nextHeader);
1245  }
1246  }
1247  }
1248  else
1249  {
1250  nhcHeader.SetNh (false);
1251  nhcHeader.SetNextHeader (nextHeader);
1252  }
1253 
1254  uint32_t blobSize = routingHeader.GetSerializedSize ();
1255  blob.AddAtStart (blobSize);
1256  routingHeader.Serialize (blob.Begin ());
1257  blob.RemoveAtStart (2);
1258  blobSize = blob.GetSize ();
1259  nhcHeader.SetBlob (blob.PeekData (), blobSize);
1260  }
1261  else if (headerType == Ipv6Header::IPV6_EXT_FRAGMENTATION)
1262  {
1263  Ipv6ExtensionFragmentHeader fragHeader;
1264  packet->PeekHeader (fragHeader);
1265  if (fragHeader.GetLength () >= 0xff)
1266  {
1267  NS_LOG_DEBUG ("LOWPAN_NHC MUST NOT be used to encode IPv6 Extension Headers "
1268  "that have more than 255 octets following the Length field after compression. "
1269  "Packet uncompressed.");
1270  return 0;
1271  }
1272  size += packet->RemoveHeader (fragHeader);
1274 
1275  // recursively compress other headers
1276  uint8_t nextHeader = fragHeader.GetNextHeader ();
1277  if (CanCompressLowPanNhc (nextHeader))
1278  {
1279  if (nextHeader == Ipv6Header::IPV6_UDP)
1280  {
1281  nhcHeader.SetNh (true);
1282  size += CompressLowPanUdpNhc (packet, m_omitUdpChecksum);
1283  }
1284  else if (nextHeader == Ipv6Header::IPV6_IPV6)
1285  {
1286  nhcHeader.SetNh (true);
1287  size += CompressLowPanIphc (packet, src, dst);
1288  }
1289  else
1290  {
1291  uint32_t sizeNhc = CompressLowPanNhc (packet, nextHeader, src, dst);
1292  // the compression might fail due to Extension header size.
1293  if (sizeNhc)
1294  {
1295  nhcHeader.SetNh (true);
1296  size += sizeNhc;
1297  }
1298  else
1299  {
1300  nhcHeader.SetNh (false);
1301  nhcHeader.SetNextHeader (nextHeader);
1302  }
1303  }
1304  }
1305  else
1306  {
1307  nhcHeader.SetNh (false);
1308  nhcHeader.SetNextHeader (nextHeader);
1309  }
1310 
1311  uint32_t blobSize = fragHeader.GetSerializedSize ();
1312  blob.AddAtStart (blobSize);
1313  fragHeader.Serialize (blob.Begin ());
1314  blob.RemoveAtStart (2);
1315  blobSize = blob.GetSize ();
1316  nhcHeader.SetBlob (blob.PeekData (), blobSize);
1317  }
1318  else if (headerType == Ipv6Header::IPV6_EXT_DESTINATION)
1319  {
1320  Ipv6ExtensionDestinationHeader destHeader;
1321  packet->PeekHeader (destHeader);
1322  if (destHeader.GetLength () >= 0xff)
1323  {
1324  NS_LOG_DEBUG ("LOWPAN_NHC MUST NOT be used to encode IPv6 Extension Headers "
1325  "that have more than 255 octets following the Length field after compression. "
1326  "Packet uncompressed.");
1327  return 0;
1328  }
1329  size += packet->RemoveHeader (destHeader);
1331 
1332  // recursively compress other headers
1333  uint8_t nextHeader = destHeader.GetNextHeader ();
1334  if (CanCompressLowPanNhc (nextHeader))
1335  {
1336  if (nextHeader == Ipv6Header::IPV6_UDP)
1337  {
1338  nhcHeader.SetNh (true);
1339  size += CompressLowPanUdpNhc (packet, m_omitUdpChecksum);
1340  }
1341  else if (nextHeader == Ipv6Header::IPV6_IPV6)
1342  {
1343  nhcHeader.SetNh (true);
1344  size += CompressLowPanIphc (packet, src, dst);
1345  }
1346  else
1347  {
1348  uint32_t sizeNhc = CompressLowPanNhc (packet, nextHeader, src, dst);
1349  // the compression might fail due to Extension header size.
1350  if (sizeNhc)
1351  {
1352  nhcHeader.SetNh (true);
1353  size += sizeNhc;
1354  }
1355  else
1356  {
1357  nhcHeader.SetNh (false);
1358  nhcHeader.SetNextHeader (nextHeader);
1359  }
1360  }
1361  }
1362  else
1363  {
1364  nhcHeader.SetNh (false);
1365  nhcHeader.SetNextHeader (nextHeader);
1366  }
1367 
1368  uint32_t blobSize = destHeader.GetSerializedSize ();
1369  blob.AddAtStart (blobSize);
1370  destHeader.Serialize (blob.Begin ());
1371  blob.RemoveAtStart (2);
1372  blobSize = blob.GetSize ();
1373  nhcHeader.SetBlob (blob.PeekData (), blobSize);
1374  }
1375  else if (headerType == Ipv6Header::IPV6_EXT_MOBILITY)
1376  {
1377  // \todo: IPv6 Mobility Header is not supported in ns-3
1378  NS_ABORT_MSG ("IPv6 Mobility Header is not supported in ns-3 yet");
1379  return 0;
1380  }
1381  else
1382  {
1383  NS_ABORT_MSG ("Unexpected Extension Header");
1384  }
1385 
1386  NS_LOG_DEBUG ("NHC Compression - NHC header size = " << nhcHeader.GetSerializedSize () );
1387  NS_LOG_DEBUG ("NHC Compression - packet size = " << packet->GetSize () );
1388 
1389  packet->AddHeader (nhcHeader);
1390 
1391  NS_LOG_DEBUG ("Packet after NHC compression: " << *packet);
1392  return size;
1393 }
1394 
1395 uint8_t
1396 SixLowPanNetDevice::DecompressLowPanNhc (Ptr<Packet> packet, Address const &src, Address const &dst, Ipv6Address srcAddress, Ipv6Address dstAddress)
1397 {
1398  NS_LOG_FUNCTION (this << *packet);
1399 
1400  SixLowPanNhcExtension encoding;
1401 
1402  uint32_t ret = packet->RemoveHeader (encoding);
1403  NS_LOG_DEBUG ("removed " << ret << " bytes - pkt is " << *packet);
1404  NS_UNUSED (ret);
1405 
1406  Ipv6ExtensionHopByHopHeader hopHeader;
1407  Ipv6ExtensionRoutingHeader routingHeader;
1408  Ipv6ExtensionFragmentHeader fragHeader;
1409  Ipv6ExtensionDestinationHeader destHeader;
1410 
1411  uint32_t blobSize;
1412  uint8_t blobData[260];
1413  blobSize = encoding.CopyBlob (blobData + 2, 260-2);
1414  uint8_t paddingSize = 0;
1415 
1416  uint8_t actualEncodedHeaderType = encoding.GetEid ();
1417  uint8_t actualHeaderType;
1418  Buffer blob;
1419 
1420  switch (actualEncodedHeaderType)
1421  {
1423  actualHeaderType = Ipv6Header::IPV6_EXT_HOP_BY_HOP;
1424  if ( encoding.GetNh () )
1425  {
1426  // Next Header
1427  uint8_t dispatchRawVal = 0;
1429 
1430  packet->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
1431  dispatchVal = SixLowPanDispatch::GetNhcDispatchType (dispatchRawVal);
1432 
1433  if (dispatchVal == SixLowPanDispatch::LOWPAN_UDPNHC)
1434  {
1435  blobData [0] = Ipv6Header::IPV6_UDP;
1436  DecompressLowPanUdpNhc (packet, srcAddress, dstAddress);
1437  }
1438  else
1439  {
1440  blobData [0] = DecompressLowPanNhc (packet, src, dst, srcAddress, dstAddress);
1441  }
1442  }
1443  else
1444  {
1445  blobData [0] = encoding.GetNextHeader ();
1446  }
1447 
1448  // manually add some padding if needed
1449  if ((blobSize + 2) % 8 > 0)
1450  {
1451  paddingSize = 8 - (blobSize + 2) % 8;
1452  }
1453  if (paddingSize == 1)
1454  {
1455  blobData[blobSize + 2] = 0;
1456  }
1457  else if (paddingSize > 1)
1458  {
1459  blobData[blobSize + 2] = 1;
1460  blobData[blobSize + 2 + 1] = paddingSize - 2;
1461  for (uint8_t i = 0; i < paddingSize - 2; i++)
1462  {
1463  blobData[blobSize + 2 + 2 + i] = 0;
1464  }
1465  }
1466  blobData [1] = ((blobSize + 2 + paddingSize) >> 3) - 1;
1467  blob.AddAtStart (blobSize + 2 + paddingSize);
1468  blob.Begin ().Write (blobData, blobSize + 2 + paddingSize);
1469  hopHeader.Deserialize (blob.Begin ());
1470 
1471  packet->AddHeader (hopHeader);
1472  break;
1473 
1475  actualHeaderType = Ipv6Header::IPV6_EXT_ROUTING;
1476  if ( encoding.GetNh () )
1477  {
1478  // Next Header
1479  uint8_t dispatchRawVal = 0;
1481 
1482  packet->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
1483  dispatchVal = SixLowPanDispatch::GetNhcDispatchType (dispatchRawVal);
1484 
1485  if (dispatchVal == SixLowPanDispatch::LOWPAN_UDPNHC)
1486  {
1487  blobData [0] = Ipv6Header::IPV6_UDP;
1488  DecompressLowPanUdpNhc (packet, srcAddress, dstAddress);
1489  }
1490  else
1491  {
1492  blobData [0] = DecompressLowPanNhc (packet, src, dst, srcAddress, dstAddress);
1493  }
1494  }
1495  else
1496  {
1497  blobData [0] = encoding.GetNextHeader ();
1498  }
1499  blobData [1] = ((blobSize + 2) >> 3) - 1;
1500  blob.AddAtStart (blobSize + 2);
1501  blob.Begin ().Write (blobData, blobSize + 2);
1502  routingHeader.Deserialize (blob.Begin ());
1503  packet->AddHeader (routingHeader);
1504  break;
1505 
1507  actualHeaderType = Ipv6Header::IPV6_EXT_FRAGMENTATION;
1508  if ( encoding.GetNh () )
1509  {
1510  // Next Header
1511  uint8_t dispatchRawVal = 0;
1513 
1514  packet->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
1515  dispatchVal = SixLowPanDispatch::GetNhcDispatchType (dispatchRawVal);
1516 
1517  if (dispatchVal == SixLowPanDispatch::LOWPAN_UDPNHC)
1518  {
1519  blobData [0] = Ipv6Header::IPV6_UDP;
1520  DecompressLowPanUdpNhc (packet, srcAddress, dstAddress);
1521  }
1522  else
1523  {
1524  blobData [0] = DecompressLowPanNhc (packet, src, dst, srcAddress, dstAddress);
1525  }
1526  }
1527  else
1528  {
1529  blobData [0] = encoding.GetNextHeader ();
1530  }
1531  blobData [1] = 0;
1532 
1533  blob.AddAtStart (blobSize + 2);
1534  blob.Begin ().Write (blobData, blobSize + 2);
1535 
1536  fragHeader.Deserialize (blob.Begin ());
1537  packet->AddHeader (fragHeader);
1538  break;
1539 
1541  actualHeaderType = Ipv6Header::IPV6_EXT_DESTINATION;
1542  if ( encoding.GetNh () )
1543  {
1544  // Next Header
1545  uint8_t dispatchRawVal = 0;
1547 
1548  packet->CopyData (&dispatchRawVal, sizeof(dispatchRawVal));
1549  dispatchVal = SixLowPanDispatch::GetNhcDispatchType (dispatchRawVal);
1550 
1551  if (dispatchVal == SixLowPanDispatch::LOWPAN_UDPNHC)
1552  {
1553  blobData [0] = Ipv6Header::IPV6_UDP;
1554  DecompressLowPanUdpNhc (packet, srcAddress, dstAddress);
1555  }
1556  else
1557  {
1558  blobData [0] = DecompressLowPanNhc (packet, src, dst, srcAddress, dstAddress);
1559  }
1560  }
1561  else
1562  {
1563  blobData [0] = encoding.GetNextHeader ();
1564  }
1565 
1566  // manually add some padding if needed
1567  if ((blobSize + 2) % 8 > 0)
1568  {
1569  paddingSize = 8 - (blobSize + 2) % 8;
1570  }
1571  if (paddingSize == 1)
1572  {
1573  blobData[blobSize + 2] = 0;
1574  }
1575  else if (paddingSize > 1)
1576  {
1577  blobData[blobSize + 2] = 1;
1578  blobData[blobSize + 2 + 1] = paddingSize - 2;
1579  for (uint8_t i = 0; i < paddingSize - 2; i++)
1580  {
1581  blobData[blobSize + 2 + 2 + i] = 0;
1582  }
1583  }
1584  blobData [1] = ((blobSize + 2 + paddingSize) >> 3) - 1;
1585  blob.AddAtStart (blobSize + 2 + paddingSize);
1586  blob.Begin ().Write (blobData, blobSize + 2 + paddingSize);
1587  destHeader.Deserialize (blob.Begin ());
1588 
1589  packet->AddHeader (destHeader);
1590  break;
1592  // \todo: IPv6 Mobility Header is not supported in ns-3
1593  NS_ABORT_MSG ("IPv6 Mobility Header is not supported in ns-3 yet");
1594  break;
1596  actualHeaderType = Ipv6Header::IPV6_IPV6;
1597  DecompressLowPanIphc (packet, src, dst);
1598  break;
1599  default:
1600  NS_ABORT_MSG ("Trying to decode unknown Extension Header");
1601  break;
1602  }
1603 
1604  NS_LOG_DEBUG ( "Rebuilt packet: " << *packet << " Size " << packet->GetSize () );
1605  return actualHeaderType;
1606 }
1607 
1608 uint32_t
1610 {
1611  NS_LOG_FUNCTION (this << *packet << int(omitChecksum));
1612 
1613  UdpHeader udpHeader;
1614  SixLowPanUdpNhcExtension udpNhcHeader;
1615  uint32_t size = 0;
1616 
1617  NS_ASSERT_MSG (packet->PeekHeader (udpHeader) != 0, "UDP header not found, abort");
1618 
1619  size += packet->RemoveHeader (udpHeader);
1620 
1621  // Set the C field and checksum
1622  udpNhcHeader.SetC (false);
1623  uint16_t checksum = udpHeader.GetChecksum ();
1624  udpNhcHeader.SetChecksum (checksum);
1625 
1626  if (omitChecksum && udpHeader.IsChecksumOk ())
1627  {
1628  udpNhcHeader.SetC (true);
1629  }
1630 
1631  // Set the value of the ports
1632  udpNhcHeader.SetSrcPort (udpHeader.GetSourcePort ());
1633  udpNhcHeader.SetDstPort (udpHeader.GetDestinationPort ());
1634 
1635  //Set the P field
1636  if ( (udpHeader.GetSourcePort () >> 4 ) == 0xf0b && (udpHeader.GetDestinationPort () >> 4 ) == 0xf0b )
1637  {
1639  }
1640  else if ( (udpHeader.GetSourcePort () >> 8 ) == 0xf0 && (udpHeader.GetDestinationPort () >> 8 ) != 0xf0 )
1641  {
1643  }
1644  else if ( (udpHeader.GetSourcePort () >> 8 ) != 0xf0 && (udpHeader.GetDestinationPort () >> 8 ) == 0xf0 )
1645  {
1647  }
1648  else
1649  {
1651  }
1652 
1653  NS_LOG_DEBUG ("UDP_NHC Compression - UDP_NHC header size = " << udpNhcHeader.GetSerializedSize () );
1654  NS_LOG_DEBUG ("UDP_NHC Compression - packet size = " << packet->GetSize () );
1655 
1656  packet->AddHeader (udpNhcHeader);
1657 
1658  NS_LOG_DEBUG ("Packet after UDP_NHC compression: " << *packet);
1659 
1660  return size;
1661 }
1662 
1663 void
1665 {
1666  NS_LOG_FUNCTION (this << *packet);
1667 
1668  UdpHeader udpHeader;
1669  SixLowPanUdpNhcExtension encoding;
1670 
1671  uint32_t ret = packet->RemoveHeader (encoding);
1672  NS_LOG_DEBUG ("removed " << ret << " bytes - pkt is " << *packet);
1673  NS_UNUSED (ret);
1674 
1675  // Set the value of the ports
1676  switch ( encoding.GetPorts () )
1677  {
1678  uint16_t temp;
1680  udpHeader.SetSourcePort (encoding.GetSrcPort ());
1681  udpHeader.SetDestinationPort (encoding.GetDstPort ());
1682  break;
1684  udpHeader.SetSourcePort (encoding.GetSrcPort ());
1685  temp = 0xf0;
1686  temp |= (temp << 8) | encoding.GetDstPort ();
1687  udpHeader.SetDestinationPort (temp);
1688  break;
1690  temp = 0xf0;
1691  temp |= (temp << 8) | encoding.GetSrcPort ();
1692  udpHeader.SetSourcePort (temp);
1693  udpHeader.SetDestinationPort (encoding.GetDstPort ());
1694  break;
1696  temp = 0xf0b;
1697  temp |= (temp << 4) | encoding.GetSrcPort ();
1698  udpHeader.SetSourcePort (temp);
1699  temp = 0xf0b;
1700  temp |= (temp << 4) | encoding.GetDstPort ();
1701  udpHeader.SetDestinationPort (temp);
1702  break;
1703  }
1704 
1705  // Get the C field and checksum
1706  if (Node::ChecksumEnabled ())
1707  {
1708  if ( encoding.GetC () )
1709  {
1710  NS_LOG_LOGIC ("Recalculating UDP Checksum");
1711  udpHeader.EnableChecksums ();
1712  udpHeader.InitializeChecksum (saddr,
1713  daddr,
1715  packet->AddHeader (udpHeader);
1716  }
1717  else
1718  {
1719  NS_LOG_LOGIC ("Forcing UDP Checksum to " << encoding.GetChecksum ());
1720  udpHeader.ForceChecksum (encoding.GetChecksum ());
1721  packet->AddHeader (udpHeader);
1722  NS_LOG_LOGIC ("UDP checksum is ok ? " << udpHeader.IsChecksumOk ());
1723  }
1724  }
1725  else
1726  {
1727  packet->AddHeader (udpHeader);
1728  }
1729 
1730  NS_LOG_DEBUG ( "Rebuilt packet: " << *packet << " Size " << packet->GetSize () );
1731 }
1732 
1734  uint32_t origPacketSize,
1735  uint32_t origHdrSize,
1736  std::list<Ptr<Packet> >& listFragments)
1737 {
1738  NS_LOG_FUNCTION (this << *packet);
1739 
1740  Ptr<Packet> p = packet->Copy ();
1741 
1742  uint16_t offsetData = 0;
1743  uint16_t offset = 0;
1744  uint16_t l2Mtu = m_netDevice->GetMtu ();
1745  uint32_t packetSize = packet->GetSize ();
1746  uint32_t compressedHeaderSize = packetSize - (origPacketSize - origHdrSize);
1747 
1748  uint16_t tag = uint16_t (m_rng->GetValue (0, 65535));
1749  NS_LOG_LOGIC ("random tag " << tag << " - test " << packetSize );
1750 
1751  // first fragment
1752  SixLowPanFrag1 frag1Hdr;
1753  frag1Hdr.SetDatagramTag (tag);
1754 
1755  uint32_t size;
1756  NS_ASSERT_MSG ( l2Mtu > frag1Hdr.GetSerializedSize (),
1757  "6LoWPAN: can not fragment, 6LoWPAN headers are bigger than MTU");
1758 
1759  size = l2Mtu - frag1Hdr.GetSerializedSize () - compressedHeaderSize;
1760  size -= size % 8;
1761  size += compressedHeaderSize;
1762 
1763  frag1Hdr.SetDatagramSize (origPacketSize);
1764 
1765  Ptr<Packet> fragment1 = p->CreateFragment (offsetData, size);
1766  offset += size + origHdrSize - compressedHeaderSize;
1767  offsetData += size;
1768 
1769  fragment1->AddHeader (frag1Hdr);
1770  listFragments.push_back (fragment1);
1771 
1772  bool moreFrag = true;
1773  do
1774  {
1775  SixLowPanFragN fragNHdr;
1776  fragNHdr.SetDatagramTag (tag);
1777  fragNHdr.SetDatagramSize (origPacketSize);
1778  fragNHdr.SetDatagramOffset ((offset) >> 3);
1779 
1780  size = l2Mtu - fragNHdr.GetSerializedSize ();
1781  size -= size % 8;
1782 
1783  if ( (offsetData + size) > packetSize )
1784  {
1785  size = packetSize - offsetData;
1786  moreFrag = false;
1787  }
1788 
1789  NS_LOG_LOGIC ("Fragment creation - " << offset << ", " << offset );
1790  Ptr<Packet> fragment = p->CreateFragment (offsetData, size);
1791  NS_LOG_LOGIC ("Fragment created - " << offset << ", " << fragment->GetSize () );
1792 
1793  offset += size;
1794  offsetData += size;
1795 
1796  fragment->AddHeader (fragNHdr);
1797  listFragments.push_back (fragment);
1798 
1799  }
1800  while (moreFrag);
1801 
1802  return;
1803 }
1804 
1805 bool SixLowPanNetDevice::ProcessFragment (Ptr<Packet>& packet, Address const &src, Address const &dst, bool isFirst)
1806 {
1807  NS_LOG_FUNCTION ( this << *packet );
1808  SixLowPanFrag1 frag1Header;
1809  SixLowPanFragN fragNHeader;
1810  FragmentKey key;
1811  uint16_t packetSize;
1812  key.first = std::pair<Address, Address> (src, dst);
1813 
1814  Ptr<Packet> p = packet->Copy ();
1815  uint16_t offset = 0;
1816 
1817  /* Implementation note:
1818  *
1819  * The fragment offset is relative to the *uncompressed* packet.
1820  * On the other hand, the packet can not be uncompressed correctly without all
1821  * its fragments, as the UDP checksum can not be computed otherwise.
1822  *
1823  * As a consequence we must uncompress the packet twice, and save its first
1824  * fragment for the final one.
1825  */
1826 
1827  if ( isFirst )
1828  {
1829  uint8_t dispatchRawValFrag1 = 0;
1830  SixLowPanDispatch::Dispatch_e dispatchValFrag1;
1831 
1832  p->RemoveHeader (frag1Header);
1833  packetSize = frag1Header.GetDatagramSize ();
1834  p->CopyData (&dispatchRawValFrag1, sizeof(dispatchRawValFrag1));
1835  dispatchValFrag1 = SixLowPanDispatch::GetDispatchType (dispatchRawValFrag1);
1836  NS_LOG_DEBUG ( "Dispatches: " << int(dispatchRawValFrag1) << " - " << int(dispatchValFrag1) );
1837  NS_LOG_DEBUG ( "Packet: " << *p );
1838 
1839  switch ( dispatchValFrag1 )
1840  {
1842  {
1843  SixLowPanIpv6 uncompressedHdr;
1844  p->RemoveHeader(uncompressedHdr);
1845  }
1846  break;
1848  DecompressLowPanHc1 (p, src, dst);
1849  break;
1851  DecompressLowPanIphc (p, src, dst);
1852  break;
1853  default:
1854  NS_FATAL_ERROR ("Unsupported 6LoWPAN encoding, exiting.");
1855  break;
1856  }
1857 
1858  key.second = std::pair<uint16_t, uint16_t> (frag1Header.GetDatagramSize (), frag1Header.GetDatagramTag ());
1859  }
1860  else
1861  {
1862  p->RemoveHeader (fragNHeader);
1863  packetSize = fragNHeader.GetDatagramSize ();
1864  offset = fragNHeader.GetDatagramOffset () << 3;
1865  key.second = std::pair<uint16_t, uint16_t> (fragNHeader.GetDatagramSize (), fragNHeader.GetDatagramTag ());
1866  }
1867 
1868  Ptr<Fragments> fragments;
1869 
1870  MapFragments_t::iterator it = m_fragments.find (key);
1871  if (it == m_fragments.end ())
1872  {
1873  // erase the oldest packet.
1875  {
1876  MapFragmentsTimers_t::iterator iter;
1877  MapFragmentsTimers_t::iterator iterFound = m_fragmentsTimers.begin ();
1878  for ( iter = m_fragmentsTimers.begin (); iter != m_fragmentsTimers.end (); iter++)
1879  {
1880  if ( iter->second.GetTs () < iterFound->second.GetTs () )
1881  {
1882  iterFound = iter;
1883  }
1884  }
1885  FragmentKey oldestKey = iterFound->first;
1886 
1887  std::list< Ptr<Packet> > storedFragments = m_fragments[oldestKey]->GetFraments ();
1888  for (std::list< Ptr<Packet> >::iterator fragIter = storedFragments.begin ();
1889  fragIter != storedFragments.end (); fragIter++)
1890  {
1892  }
1893 
1894  m_fragmentsTimers[oldestKey].Cancel ();
1895  m_fragmentsTimers.erase (oldestKey);
1896  m_fragments[oldestKey] = 0;
1897  m_fragments.erase (oldestKey);
1898 
1899  }
1900  fragments = Create<Fragments> ();
1901  fragments->SetPacketSize (packetSize);
1902  m_fragments.insert (std::make_pair (key, fragments));
1903  uint32_t ifIndex = GetIfIndex ();
1906  key, ifIndex);
1907  }
1908  else
1909  {
1910  fragments = it->second;
1911  }
1912 
1913  fragments->AddFragment (p, offset);
1914 
1915  // add the very first fragment so we can correctly decode the packet once is rebuilt.
1916  // this is needed because otherwise the UDP header length and checksum can not be calculated.
1917  if ( isFirst )
1918  {
1919  fragments->AddFirstFragment (packet);
1920  }
1921 
1922  if ( fragments->IsEntire () )
1923  {
1924  packet = fragments->GetPacket ();
1925  NS_LOG_LOGIC ("Reconstructed packet: " << *packet);
1926 
1927  SixLowPanFrag1 frag1Header;
1928  packet->RemoveHeader (frag1Header);
1929 
1930  NS_LOG_LOGIC ("Rebuilt packet. Size " << packet->GetSize () << " - " << *packet);
1931  fragments = 0;
1932  m_fragments.erase (key);
1933  if (m_fragmentsTimers[key].IsRunning ())
1934  {
1935  NS_LOG_LOGIC ("Stopping 6LoWPAN WaitFragmentsTimer at " << Simulator::Now ().GetSeconds () << " due to complete packet");
1936  m_fragmentsTimers[key].Cancel ();
1937  }
1938  m_fragmentsTimers.erase (key);
1939  return true;
1940  }
1941 
1942  return false;
1943 }
1944 
1946 {
1947  NS_LOG_FUNCTION (this);
1948  m_packetSize = 0;
1949 }
1950 
1952 {
1953  NS_LOG_FUNCTION (this);
1954 }
1955 
1956 void SixLowPanNetDevice::Fragments::AddFragment (Ptr<Packet> fragment, uint16_t fragmentOffset)
1957 {
1958  NS_LOG_FUNCTION (this << fragmentOffset << *fragment);
1959 
1960  std::list<std::pair<Ptr<Packet>, uint16_t> >::iterator it;
1961  bool duplicate = false;
1962 
1963  for (it = m_fragments.begin (); it != m_fragments.end (); it++)
1964  {
1965  if (it->second > fragmentOffset)
1966  {
1967  break;
1968  }
1969  if (it->second == fragmentOffset)
1970  {
1971  duplicate = true;
1972  NS_ASSERT_MSG (fragment->GetSize () == it->first->GetSize (), "Duplicate fragment size differs. Aborting.");
1973  break;
1974  }
1975  }
1976  if (!duplicate)
1977  {
1978  m_fragments.insert (it, std::make_pair (fragment, fragmentOffset));
1979  }
1980 }
1981 
1983 {
1984  NS_LOG_FUNCTION (this << *fragment);
1985 
1986  m_firstFragment = fragment;
1987 }
1988 
1990 {
1991  NS_LOG_FUNCTION (this);
1992 
1993  bool ret = m_fragments.size () > 0;
1994  uint16_t lastEndOffset = 0;
1995 
1996  if (ret)
1997  {
1998  for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
1999  {
2000  // overlapping fragments should not exist
2001  NS_LOG_LOGIC ("Checking overlaps " << lastEndOffset << " - " << it->second );
2002 
2003  if (lastEndOffset < it->second)
2004  {
2005  ret = false;
2006  break;
2007  }
2008  // fragments might overlap in strange ways
2009  uint16_t fragmentEnd = it->first->GetSize () + it->second;
2010  lastEndOffset = std::max ( lastEndOffset, fragmentEnd );
2011  }
2012  }
2013 
2014  if ( ret && (lastEndOffset == m_packetSize))
2015  {
2016  return true;
2017  }
2018  return false;
2019 }
2020 
2022 {
2023  NS_LOG_FUNCTION (this);
2024 
2025  std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin ();
2026 
2027  Ptr<Packet> p = Create<Packet> ();
2028  uint16_t lastEndOffset = 0;
2029 
2030  p->AddAtEnd (m_firstFragment);
2031  it = m_fragments.begin ();
2032  lastEndOffset = it->first->GetSize ();
2033 
2034  for ( it++; it != m_fragments.end (); it++)
2035  {
2036  if ( lastEndOffset > it->second )
2037  {
2038  NS_ABORT_MSG ("Overlapping fragments found, forbidden condition");
2039  }
2040  else
2041  {
2042  NS_LOG_LOGIC ("Adding: " << *(it->first) );
2043  p->AddAtEnd (it->first);
2044  }
2045  lastEndOffset += it->first->GetSize ();
2046  }
2047 
2048  return p;
2049 }
2050 
2052 {
2053  NS_LOG_FUNCTION (this << packetSize);
2054  m_packetSize = packetSize;
2055 }
2056 
2057 std::list< Ptr<Packet> > SixLowPanNetDevice::Fragments::GetFraments () const
2058 {
2059  std::list< Ptr<Packet> > fragments;
2060  std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator iter;
2061  for ( iter = m_fragments.begin (); iter != m_fragments.end (); iter ++)
2062  {
2063  fragments.push_back (iter->first);
2064  }
2065  return fragments;
2066 }
2067 
2069 {
2070  NS_LOG_FUNCTION (this);
2071 
2072  MapFragments_t::iterator it = m_fragments.find (key);
2073  std::list< Ptr<Packet> > storedFragments = it->second->GetFraments ();
2074  for (std::list< Ptr<Packet> >::iterator fragIter = storedFragments.begin ();
2075  fragIter != storedFragments.end (); fragIter++)
2076  {
2078  }
2079  // clear the buffers
2080  it->second = 0;
2081 
2082  m_fragments.erase (key);
2083  m_fragmentsTimers.erase (key);
2084 }
2085 
2087 {
2088  Ipv6Address ipv6Addr = Ipv6Address::GetAny ();
2089 
2091  {
2093  }
2094  else
2095  {
2096  if (Mac64Address::IsMatchingType (addr))
2097  {
2099  }
2100  else if (Mac16Address::IsMatchingType (addr))
2101  {
2103  }
2104  }
2105  if (ipv6Addr.IsAny ())
2106  {
2107  NS_ABORT_MSG ("Unknown address type");
2108  }
2109  return ipv6Addr;
2110 }
2111 
2113 {
2114  Ipv6Address ipv6Addr = Ipv6Address::GetAny ();
2115 
2117  {
2119  }
2120  else
2121  {
2122  if (Mac64Address::IsMatchingType (addr))
2123  {
2125  }
2126  else if (Mac16Address::IsMatchingType (addr))
2127  {
2129  }
2130  }
2131  if (ipv6Addr.IsAny ())
2132  {
2133  NS_ABORT_MSG ("Unknown address type");
2134  }
2135  return ipv6Addr;
2136 }
2137 
2138 }
2139 
2140 // 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:50
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:80
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:65
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:276
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:368
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:538
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:75
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:313
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
#define max(a, b)
Definition: 80211b.c:45
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:60
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:278
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:90
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:227
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:95
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:48
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:85
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:337
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:100
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:55
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:45
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:356
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:105
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:257
Ipv6Address GetDestinationAddress(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:110
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.