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