A Discrete-Event Network Simulator
API
sixlowpan-header.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Universita' di Firenze, Italy
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Tommaso Pecorella <tommaso.pecorella@unifi.it>
18  * Michele Muccio <michelemuccio@virgilio.it>
19  */
20 
21 #include "sixlowpan-header.h"
22 
23 #include "ns3/abort.h"
24 #include "ns3/assert.h"
25 #include "ns3/ipv6-header.h"
26 #include "ns3/log.h"
27 #include "ns3/mac16-address.h"
28 #include "ns3/mac64-address.h"
29 
30 namespace ns3
31 {
32 
33 /*
34  * SixLowPanDispatch
35  */
36 
38 {
39 }
40 
43 {
44  if (dispatch <= LOWPAN_NALP_N)
45  {
46  return LOWPAN_NALP;
47  }
48  else if (dispatch == LOWPAN_IPv6)
49  {
50  return LOWPAN_IPv6;
51  }
52  else if (dispatch == LOWPAN_HC1)
53  {
54  return LOWPAN_HC1;
55  }
56  else if (dispatch == LOWPAN_BC0)
57  {
58  return LOWPAN_BC0;
59  }
60  else if ((dispatch >= LOWPAN_IPHC) && (dispatch <= LOWPAN_IPHC_N))
61  {
62  return LOWPAN_IPHC;
63  }
64  else if ((dispatch >= LOWPAN_MESH) && (dispatch <= LOWPAN_MESH_N))
65  {
66  return LOWPAN_MESH;
67  }
68  else if ((dispatch >= LOWPAN_FRAG1) && (dispatch <= LOWPAN_FRAG1_N))
69  {
70  return LOWPAN_FRAG1;
71  }
72  else if ((dispatch >= LOWPAN_FRAGN) && (dispatch <= LOWPAN_FRAGN_N))
73  {
74  return LOWPAN_FRAGN;
75  }
76  return LOWPAN_UNSUPPORTED;
77 }
78 
81 {
82  if ((dispatch >= LOWPAN_NHC) && (dispatch <= LOWPAN_NHC_N))
83  {
84  return LOWPAN_NHC;
85  }
86  else if ((dispatch >= LOWPAN_UDPNHC) && (dispatch <= LOWPAN_UDPNHC_N))
87  {
88  return LOWPAN_UDPNHC;
89  }
90  return LOWPAN_NHCUNSUPPORTED;
91 }
92 
93 /*
94  * SixLowPanHc1
95  */
97 
99  : m_hopLimit(0)
100 {
101 }
102 
103 TypeId
105 {
106  static TypeId tid = TypeId("ns3::SixLowPanHc1")
107  .SetParent<Header>()
108  .SetGroupName("SixLowPan")
109  .AddConstructor<SixLowPanHc1>();
110  return tid;
111 }
112 
113 TypeId
115 {
116  return GetTypeId();
117 }
118 
119 void
120 SixLowPanHc1::Print(std::ostream& os) const
121 {
122  uint8_t encoding;
124  encoding <<= 2;
126  encoding <<= 1;
128  encoding <<= 2;
130  encoding <<= 1;
132 
133  os << "encoding " << +encoding << ", hopLimit " << +m_hopLimit;
134 }
135 
136 uint32_t
138 {
139  uint32_t serializedSize = 3;
140 
141  switch (m_srcCompression)
142  {
143  case HC1_PIII:
144  serializedSize += 16;
145  break;
146  case HC1_PIIC:
147  serializedSize += 8;
148  break;
149  case HC1_PCII:
150  serializedSize += 8;
151  break;
152  case HC1_PCIC:
153  break;
154  }
155  switch (m_dstCompression)
156  {
157  case HC1_PIII:
158  serializedSize += 16;
159  break;
160  case HC1_PIIC:
161  serializedSize += 8;
162  break;
163  case HC1_PCII:
164  serializedSize += 8;
165  break;
166  case HC1_PCIC:
167  break;
168  }
169 
170  if (!m_tcflCompression)
171  {
172  serializedSize += 4;
173  }
174 
176  {
177  serializedSize++;
178  }
179 
180  return serializedSize;
181 }
182 
183 void
185 {
187  uint8_t encoding;
189  encoding <<= 2;
191  encoding <<= 1;
193  encoding <<= 2;
195  encoding <<= 1;
197 
199  i.WriteU8(encoding);
200  i.WriteU8(m_hopLimit);
201  switch (m_srcCompression)
202  {
203  case HC1_PIII:
204  for (int j = 0; j < 8; j++)
205  {
206  i.WriteU8(m_srcPrefix[j]);
207  }
208  for (int j = 0; j < 8; j++)
209  {
210  i.WriteU8(m_srcInterface[j]);
211  }
212  break;
213  case HC1_PIIC:
214  for (int j = 0; j < 8; j++)
215  {
216  i.WriteU8(m_srcPrefix[j]);
217  }
218  break;
219  case HC1_PCII:
220  for (int j = 0; j < 8; j++)
221  {
222  i.WriteU8(m_srcInterface[j]);
223  }
224  break;
225  case HC1_PCIC:
226  break;
227  }
228  switch (m_dstCompression)
229  {
230  case HC1_PIII:
231  for (int j = 0; j < 8; j++)
232  {
233  i.WriteU8(m_dstPrefix[j]);
234  }
235  for (int j = 0; j < 8; j++)
236  {
237  i.WriteU8(m_dstInterface[j]);
238  }
239  break;
240  case HC1_PIIC:
241  for (int j = 0; j < 8; j++)
242  {
243  i.WriteU8(m_dstPrefix[j]);
244  }
245  break;
246  case HC1_PCII:
247  for (int j = 0; j < 8; j++)
248  {
249  i.WriteU8(m_dstInterface[j]);
250  }
251  break;
252  case HC1_PCIC:
253  break;
254  }
255 
256  if (!m_tcflCompression)
257  {
259  uint8_t temp[3];
260  temp[0] = uint8_t(m_flowLabel & 0xff);
261  temp[1] = uint8_t((m_flowLabel >> 8) & 0xff);
262  temp[2] = uint8_t((m_flowLabel >> 16) & 0xff);
263  i.Write(temp, 3);
264  }
265 
267  {
269  }
270 
271  // TODO: HC2 is not yet supported. Should be.
272  NS_ASSERT_MSG(m_hc2HeaderPresent != true, "Can not compress HC2, exiting. Very sorry.");
273 }
274 
275 uint32_t
277 {
279 
280  uint8_t dispatch = i.ReadU8();
281  if (dispatch != SixLowPanDispatch::LOWPAN_HC1)
282  {
283  return 0;
284  }
285 
286  uint8_t encoding = i.ReadU8();
287  m_hopLimit = i.ReadU8();
288 
290  m_dstCompression = LowPanHc1Addr_e((encoding >> 4) & 0x3);
291  m_tcflCompression = (encoding >> 3) & 0x1;
294 
295  switch (m_srcCompression)
296  {
297  case HC1_PIII:
298  for (int j = 0; j < 8; j++)
299  {
300  m_srcPrefix[j] = i.ReadU8();
301  }
302  for (int j = 0; j < 8; j++)
303  {
304  m_srcInterface[j] = i.ReadU8();
305  }
306  break;
307  case HC1_PIIC:
308  for (int j = 0; j < 8; j++)
309  {
310  m_srcPrefix[j] = i.ReadU8();
311  }
312  break;
313  case HC1_PCII:
314  for (int j = 0; j < 8; j++)
315  {
316  m_srcInterface[j] = i.ReadU8();
317  }
318  break;
319  case HC1_PCIC:
320  break;
321  }
322  switch (m_dstCompression)
323  {
324  case HC1_PIII:
325  for (int j = 0; j < 8; j++)
326  {
327  m_dstPrefix[j] = i.ReadU8();
328  }
329  for (int j = 0; j < 8; j++)
330  {
331  m_dstInterface[j] = i.ReadU8();
332  }
333  break;
334  case HC1_PIIC:
335  for (int j = 0; j < 8; j++)
336  {
337  m_dstPrefix[j] = i.ReadU8();
338  }
339  break;
340  case HC1_PCII:
341  for (int j = 0; j < 8; j++)
342  {
343  m_dstInterface[j] = i.ReadU8();
344  }
345  break;
346  case HC1_PCIC:
347  break;
348  }
349 
350  if (!m_tcflCompression)
351  {
352  m_trafficClass = i.ReadU8();
353  uint8_t temp[3];
354  i.Read(temp, 3);
355  m_flowLabel = temp[2];
356  m_flowLabel = (m_flowLabel << 8) | temp[1];
357  m_flowLabel = (m_flowLabel << 8) | temp[0];
358  }
359 
360  switch (m_nextHeaderCompression)
361  {
362  case HC1_NC:
363  m_nextHeader = i.ReadU8();
364  break;
365  case HC1_TCP:
367  break;
368  case HC1_UDP:
370  break;
371  case HC1_ICMP:
373  break;
374  }
375 
376  NS_ASSERT_MSG(m_hc2HeaderPresent != true, "Can not compress HC2, exiting. Very sorry.");
377 
378  return GetSerializedSize();
379 }
380 
381 void
383 {
384  m_hopLimit = limit;
385 }
386 
387 uint8_t
389 {
390  return m_hopLimit;
391 }
392 
395 {
396  return m_dstCompression;
397 }
398 
399 const uint8_t*
401 {
402  return m_dstInterface;
403 }
404 
405 const uint8_t*
407 {
408  return m_dstPrefix;
409 }
410 
411 uint32_t
413 {
414  return m_flowLabel;
415 }
416 
417 uint8_t
419 {
420  return m_nextHeader;
421 }
422 
425 {
426  return m_srcCompression;
427 }
428 
429 const uint8_t*
431 {
432  return m_srcInterface;
433 }
434 
435 const uint8_t*
437 {
438  return m_srcPrefix;
439 }
440 
441 uint8_t
443 {
444  return m_trafficClass;
445 }
446 
447 bool
449 {
450  return m_tcflCompression;
451 }
452 
453 bool
455 {
456  return m_hc2HeaderPresent;
457 }
458 
459 void
461 {
462  m_dstCompression = dstCompression;
463 }
464 
465 void
466 SixLowPanHc1::SetDstInterface(const uint8_t* dstInterface)
467 {
468  for (int i = 0; i < 8; i++)
469  {
470  m_dstInterface[i] = dstInterface[i];
471  }
472 }
473 
474 void
475 SixLowPanHc1::SetDstPrefix(const uint8_t* dstPrefix)
476 {
477  for (int i = 0; i < 8; i++)
478  {
479  m_dstPrefix[i] = dstPrefix[i];
480  }
481 }
482 
483 void
484 SixLowPanHc1::SetFlowLabel(uint32_t flowLabel)
485 {
486  m_flowLabel = flowLabel;
487 }
488 
489 void
490 SixLowPanHc1::SetNextHeader(uint8_t nextHeader)
491 {
492  m_nextHeader = nextHeader;
493 
494  switch (m_nextHeader)
495  {
498  break;
501  break;
504  break;
505  default:
507  break;
508  }
509 }
510 
511 void
513 {
514  m_srcCompression = srcCompression;
515 }
516 
517 void
518 SixLowPanHc1::SetSrcInterface(const uint8_t* srcInterface)
519 {
520  for (int i = 0; i < 8; i++)
521  {
522  m_srcInterface[i] = srcInterface[i];
523  }
524 }
525 
526 void
527 SixLowPanHc1::SetSrcPrefix(const uint8_t* srcPrefix)
528 {
529  for (int i = 0; i < 8; i++)
530  {
531  m_srcPrefix[i] = srcPrefix[i];
532  }
533 }
534 
535 void
536 SixLowPanHc1::SetTcflCompression(bool tcflCompression)
537 {
538  m_tcflCompression = tcflCompression;
539 }
540 
541 void
542 SixLowPanHc1::SetTrafficClass(uint8_t trafficClass)
543 {
544  m_trafficClass = trafficClass;
545 }
546 
547 void
548 SixLowPanHc1::SetHc2HeaderPresent(bool hc2HeaderPresent)
549 {
550  m_hc2HeaderPresent = hc2HeaderPresent;
551 }
552 
553 std::ostream&
554 operator<<(std::ostream& os, const SixLowPanHc1& h)
555 {
556  h.Print(os);
557  return os;
558 }
559 
560 /*
561  * SixLowPanFrag1
562  */
563 NS_OBJECT_ENSURE_REGISTERED(SixLowPanFrag1);
564 
566  : m_datagramSize(0),
567  m_datagramTag(0)
568 {
569 }
570 
571 TypeId
573 {
574  static TypeId tid = TypeId("ns3::SixLowPanFrag1")
575  .SetParent<Header>()
576  .SetGroupName("SixLowPan")
577  .AddConstructor<SixLowPanFrag1>();
578  return tid;
579 }
580 
581 TypeId
583 {
584  return GetTypeId();
585 }
586 
587 void
588 SixLowPanFrag1::Print(std::ostream& os) const
589 {
590  os << "datagram size " << m_datagramSize << " tag " << m_datagramTag;
591 }
592 
593 uint32_t
595 {
596  return 4;
597 }
598 
599 void
601 {
603 
604  uint16_t temp = m_datagramSize | (uint16_t(SixLowPanDispatch::LOWPAN_FRAG1) << 8);
605 
606  i.WriteU8(uint8_t(temp >> 8));
607  i.WriteU8(uint8_t(temp & 0xff));
608 
610 }
611 
612 uint32_t
614 {
616 
617  uint8_t temp = i.ReadU8();
618  m_datagramSize = (uint16_t(temp) << 8) | i.ReadU8();
619  m_datagramSize &= 0x7FF;
620 
621  m_datagramTag = i.ReadU16();
622  return GetSerializedSize();
623 }
624 
625 void
626 SixLowPanFrag1::SetDatagramSize(uint16_t datagramSize)
627 {
628  m_datagramSize = datagramSize & 0x7FF;
629 }
630 
631 uint16_t
633 {
634  return m_datagramSize & 0x7FF;
635 }
636 
637 void
638 SixLowPanFrag1::SetDatagramTag(uint16_t datagramTag)
639 {
640  m_datagramTag = datagramTag;
641 }
642 
643 uint16_t
645 {
646  return m_datagramTag;
647 }
648 
649 std::ostream&
650 operator<<(std::ostream& os, const SixLowPanFrag1& h)
651 {
652  h.Print(os);
653  return os;
654 }
655 
656 /*
657  * SixLowPanFragN
658  */
659 
660 NS_OBJECT_ENSURE_REGISTERED(SixLowPanFragN);
661 
663  : m_datagramSize(0),
664  m_datagramTag(0),
665  m_datagramOffset(0)
666 {
667 }
668 
669 /*
670  * SixLowPanFragmentOffset
671  */
672 TypeId
674 {
675  static TypeId tid = TypeId("ns3::SixLowPanFragN")
676  .SetParent<Header>()
677  .SetGroupName("SixLowPan")
678  .AddConstructor<SixLowPanFragN>();
679  return tid;
680 }
681 
682 TypeId
684 {
685  return GetTypeId();
686 }
687 
688 void
689 SixLowPanFragN::Print(std::ostream& os) const
690 {
691  os << "datagram size " << m_datagramSize << " tag " << m_datagramTag << " offset "
692  << +m_datagramOffset;
693 }
694 
695 uint32_t
697 {
698  return 5;
699 }
700 
701 void
703 {
705 
706  uint16_t temp = m_datagramSize | (uint16_t(SixLowPanDispatch::LOWPAN_FRAGN) << 8);
707 
708  i.WriteU8(uint8_t(temp >> 8));
709  i.WriteU8(uint8_t(temp & 0xff));
710 
713 }
714 
715 uint32_t
717 {
719 
720  uint8_t temp = i.ReadU8();
721  m_datagramSize = (uint16_t(temp) << 8) | i.ReadU8();
722  m_datagramSize &= 0x7FF;
723 
724  m_datagramTag = i.ReadU16();
725  m_datagramOffset = i.ReadU8();
726 
727  return GetSerializedSize();
728 }
729 
730 void
731 SixLowPanFragN::SetDatagramSize(uint16_t datagramSize)
732 {
733  m_datagramSize = datagramSize & 0x7FF;
734 }
735 
736 uint16_t
738 {
739  return m_datagramSize & 0x7FF;
740 }
741 
742 void
743 SixLowPanFragN::SetDatagramTag(uint16_t datagramTag)
744 {
745  m_datagramTag = datagramTag;
746 }
747 
748 uint16_t
750 {
751  return m_datagramTag;
752 }
753 
754 void
755 SixLowPanFragN::SetDatagramOffset(uint8_t datagramOffset)
756 {
757  m_datagramOffset = datagramOffset;
758 }
759 
760 uint8_t
762 {
763  return m_datagramOffset;
764 }
765 
766 std::ostream&
767 operator<<(std::ostream& os, const SixLowPanFragN& h)
768 {
769  h.Print(os);
770  return os;
771 }
772 
773 /*
774  * SixLowPanIpv6
775  */
776 
777 NS_OBJECT_ENSURE_REGISTERED(SixLowPanIpv6);
778 
780 {
781 }
782 
783 TypeId
785 {
786  static TypeId tid = TypeId("ns3::SixLowPanIpv6")
787  .SetParent<Header>()
788  .SetGroupName("SixLowPan")
789  .AddConstructor<SixLowPanIpv6>();
790  return tid;
791 }
792 
793 TypeId
795 {
796  return GetTypeId();
797 }
798 
799 void
800 SixLowPanIpv6::Print(std::ostream& os) const
801 {
802  os << "Uncompressed IPv6";
803 }
804 
805 uint32_t
807 {
808  return 1;
809 }
810 
811 void
813 {
815 
817 }
818 
819 uint32_t
821 {
823  i.ReadU8();
824 
825  return GetSerializedSize();
826 }
827 
828 std::ostream&
829 operator<<(std::ostream& os, const SixLowPanIpv6& h)
830 {
831  h.Print(os);
832  return os;
833 }
834 
835 /*
836  * SixLowPanIphcHeader
837  */
838 NS_OBJECT_ENSURE_REGISTERED(SixLowPanIphc);
839 
841 {
842  // 011x xxxx xxxx xxxx
843  m_baseFormat = 0x6000;
844  m_srcdstContextId = 0;
845 }
846 
848 {
849  // 011x xxxx xxxx xxxx
850  m_baseFormat = dispatch;
851  m_baseFormat <<= 8;
852  m_srcdstContextId = 0;
853 }
854 
855 TypeId
857 {
858  static TypeId tid = TypeId("ns3::SixLowPanIphc")
859  .SetParent<Header>()
860  .SetGroupName("SixLowPan")
861  .AddConstructor<SixLowPanIphc>();
862  return tid;
863 }
864 
865 TypeId
867 {
868  return GetTypeId();
869 }
870 
871 void
872 SixLowPanIphc::Print(std::ostream& os) const
873 {
874  switch (GetTf())
875  {
876  case TF_FULL:
877  os << "TF_FULL(" << +m_ecn << ", " << +m_dscp << ", " << m_flowLabel << ")";
878  break;
879  case TF_DSCP_ELIDED:
880  os << "TF_DSCP_ELIDED(" << +m_ecn << ", " << m_flowLabel << ")";
881  break;
882  case TF_FL_ELIDED:
883  os << "TF_FL_ELIDED(" << +m_ecn << ", " << +m_dscp << ")";
884  break;
885  default:
886  os << "TF_ELIDED";
887  break;
888  }
889 
890  GetNh() ? os << " NH(1)" : os << " NH(0)";
891 
892  switch (GetHlim())
893  {
894  case HLIM_INLINE:
895  os << " HLIM_INLINE(" << +m_hopLimit << ")";
896  break;
897  case HLIM_COMPR_1:
898  os << " HLIM_COMPR_1(1)";
899  break;
900  case HLIM_COMPR_64:
901  os << " HLIM_COMPR_64(64)";
902  break;
903  default:
904  os << " HLIM_COMPR_255(255)";
905  break;
906  }
907 
908  GetCid() ? os << " CID(" << +m_srcdstContextId << ")" : os << " CID(0)";
909 
910  GetSac() ? os << " SAC(1)" : os << " SAC(0)";
911  os << " SAM (" << GetSam() << ")";
912 
913  GetM() ? os << " M(1)" : os << " M(0)";
914  GetDac() ? os << " DAC(1)" : os << " DAC(0)";
915  os << " DAM (" << GetDam() << ")";
916 }
917 
918 uint32_t
920 {
921  uint32_t serializedSize = 2;
922 
923  if (GetCid())
924  {
925  serializedSize++;
926  }
927  switch (GetTf())
928  {
929  case TF_FULL:
930  serializedSize += 4;
931  break;
932  case TF_DSCP_ELIDED:
933  serializedSize += 3;
934  break;
935  case TF_FL_ELIDED:
936  serializedSize++;
937  break;
938  default:
939  break;
940  }
941  if (!GetNh())
942  {
943  serializedSize++;
944  }
945  if (GetHlim() == HLIM_INLINE)
946  {
947  serializedSize++;
948  }
949  switch (GetSam())
950  {
951  case HC_INLINE:
952  if (!GetSac())
953  {
954  serializedSize += 16;
955  }
956  break;
957  case HC_COMPR_64:
958  serializedSize += 8;
959  break;
960  case HC_COMPR_16:
961  serializedSize += 2;
962  break;
963  case HC_COMPR_0:
964  default:
965  break;
966  }
967  if (!GetM())
968  {
969  switch (GetDam())
970  {
971  case HC_INLINE:
972  if (!GetDac())
973  {
974  serializedSize += 16;
975  }
976  break;
977  case HC_COMPR_64:
978  serializedSize += 8;
979  break;
980  case HC_COMPR_16:
981  serializedSize += 2;
982  break;
983  case HC_COMPR_0:
984  default:
985  break;
986  }
987  }
988  else
989  {
990  switch (GetDam())
991  {
992  case HC_INLINE:
993  if (!GetDac())
994  {
995  serializedSize += 16;
996  }
997  else
998  {
999  serializedSize += 6;
1000  }
1001  break;
1002  case HC_COMPR_64:
1003  if (!GetDac())
1004  {
1005  serializedSize += 6;
1006  }
1007  break;
1008  case HC_COMPR_16:
1009  if (!GetDac())
1010  {
1011  serializedSize += 4;
1012  }
1013  break;
1014  case HC_COMPR_0:
1015  default:
1016  if (!GetDac())
1017  {
1018  serializedSize++;
1019  }
1020  break;
1021  }
1022  }
1023 
1024  return serializedSize;
1025 }
1026 
1027 void
1029 {
1030  Buffer::Iterator i = start;
1031 
1033 
1034  if (GetCid())
1035  {
1037  }
1038  // Traffic Class and Flow Label
1039  switch (GetTf())
1040  {
1041  uint8_t temp;
1042  case TF_FULL:
1043  temp = (m_ecn << 6) | m_dscp;
1044  i.WriteU8(temp);
1045  temp = m_flowLabel >> 16;
1046  i.WriteU8(temp);
1047  temp = (m_flowLabel >> 8) & 0xff;
1048  i.WriteU8(temp);
1049  temp = m_flowLabel & 0xff;
1050  i.WriteU8(temp);
1051  break;
1052  case TF_DSCP_ELIDED:
1053  temp = (m_ecn << 6) | (m_flowLabel >> 16);
1054  i.WriteU8(temp);
1055  temp = (m_flowLabel >> 8) & 0xff;
1056  i.WriteU8(temp);
1057  temp = m_flowLabel & 0xff;
1058  i.WriteU8(temp);
1059  break;
1060  case TF_FL_ELIDED:
1061  temp = (m_ecn << 6) | m_dscp;
1062  i.WriteU8(temp);
1063  break;
1064  default:
1065  break;
1066  }
1067  // Next Header
1068  if (!GetNh())
1069  {
1070  i.WriteU8(m_nextHeader);
1071  }
1072  // Hop Limit
1073  if (GetHlim() == HLIM_INLINE)
1074  {
1075  i.WriteU8(m_hopLimit);
1076  }
1077  // Source Address
1078  switch (GetSam())
1079  {
1080  case HC_INLINE:
1081  if (!GetSac())
1082  {
1083  i.Write(m_srcInlinePart, 16);
1084  }
1085  break;
1086  case HC_COMPR_64:
1087  i.Write(m_srcInlinePart, 8);
1088  break;
1089  case HC_COMPR_16:
1090  i.Write(m_srcInlinePart, 2);
1091  break;
1092  case HC_COMPR_0:
1093  default:
1094  break;
1095  }
1096  // Destination Address
1097  if (!GetM())
1098  {
1099  // unicast
1100  switch (GetDam())
1101  {
1102  case HC_INLINE:
1103  i.Write(m_dstInlinePart, 16);
1104  break;
1105  case HC_COMPR_64:
1106  i.Write(m_dstInlinePart, 8);
1107  break;
1108  case HC_COMPR_16:
1109  i.Write(m_dstInlinePart, 2);
1110  break;
1111  case HC_COMPR_0:
1112  default:
1113  break;
1114  }
1115  }
1116  else
1117  {
1118  // multicast
1119  switch (GetDam())
1120  {
1121  case HC_INLINE:
1122  i.Write(m_dstInlinePart, 16);
1123  break;
1124  case HC_COMPR_64:
1125  i.Write(m_dstInlinePart, 6);
1126  break;
1127  case HC_COMPR_16:
1128  i.Write(m_dstInlinePart, 4);
1129  break;
1130  case HC_COMPR_0:
1131  i.Write(m_dstInlinePart, 1);
1132  break;
1133  default:
1134  break;
1135  }
1136  }
1137 }
1138 
1139 uint32_t
1141 {
1142  Buffer::Iterator i = start;
1143 
1144  m_baseFormat = i.ReadNtohU16();
1145 
1146  if (GetCid())
1147  {
1148  m_srcdstContextId = i.ReadU8();
1149  }
1150  else
1151  {
1152  m_srcdstContextId = 0;
1153  }
1154  // Traffic Class and Flow Label
1155  switch (GetTf())
1156  {
1157  uint8_t temp;
1158  case TF_FULL:
1159  temp = i.ReadU8();
1160  m_ecn = temp >> 6;
1161  m_dscp = temp & 0x3F;
1162  temp = i.ReadU8();
1163  m_flowLabel = temp;
1164  temp = i.ReadU8();
1165  m_flowLabel = (m_flowLabel << 8) | temp;
1166  temp = i.ReadU8();
1167  m_flowLabel = (m_flowLabel << 8) | temp;
1168  break;
1169  case TF_DSCP_ELIDED:
1170  temp = i.ReadU8();
1171  m_ecn = temp >> 6;
1172  m_flowLabel = temp & 0x3F;
1173  temp = i.ReadU8();
1174  m_flowLabel = (m_flowLabel << 8) | temp;
1175  temp = i.ReadU8();
1176  m_flowLabel = (m_flowLabel << 8) | temp;
1177  break;
1178  case TF_FL_ELIDED:
1179  temp = i.ReadU8();
1180  m_ecn = temp >> 6;
1181  m_dscp = temp & 0x3F;
1182  break;
1183  default:
1184  break;
1185  }
1186  // Next Header
1187  if (!GetNh())
1188  {
1189  m_nextHeader = i.ReadU8();
1190  }
1191  // Hop Limit
1192  switch (GetHlim())
1193  {
1194  case HLIM_INLINE:
1195  m_hopLimit = i.ReadU8();
1196  break;
1197  case HLIM_COMPR_1:
1198  m_hopLimit = 1;
1199  break;
1200  case HLIM_COMPR_64:
1201  m_hopLimit = 64;
1202  break;
1203  case HLIM_COMPR_255:
1204  default:
1205  m_hopLimit = 255;
1206  break;
1207  }
1208  // Source Address
1209  memset(m_srcInlinePart, 0x00, sizeof(m_srcInlinePart));
1210  switch (GetSam())
1211  {
1212  case HC_INLINE:
1213  if (!GetSac())
1214  {
1215  i.Read(m_srcInlinePart, 16);
1216  }
1217  break;
1218  case HC_COMPR_64:
1219  i.Read(m_srcInlinePart, 8);
1220  break;
1221  case HC_COMPR_16:
1222  i.Read(m_srcInlinePart, 2);
1223  break;
1224  case HC_COMPR_0:
1225  default:
1226  break;
1227  }
1228 
1229  // Destination Address
1230  memset(m_dstInlinePart, 0x00, sizeof(m_dstInlinePart));
1231  if (!GetM())
1232  {
1233  // unicast
1234  switch (GetDam())
1235  {
1236  case HC_INLINE:
1237  i.Read(m_dstInlinePart, 16);
1238  break;
1239  case HC_COMPR_64:
1240  i.Read(m_dstInlinePart, 8);
1241  break;
1242  case HC_COMPR_16:
1243  i.Read(m_dstInlinePart, 2);
1244  break;
1245  case HC_COMPR_0:
1246  default:
1247  break;
1248  }
1249  }
1250  else
1251  {
1252  // multicast
1253  switch (GetDam())
1254  {
1255  case HC_INLINE:
1256  i.Read(m_dstInlinePart, 16);
1257  break;
1258  case HC_COMPR_64:
1259  i.Read(m_dstInlinePart, 6);
1260  break;
1261  case HC_COMPR_16:
1262  i.Read(m_dstInlinePart, 4);
1263  break;
1264  case HC_COMPR_0:
1265  i.Read(m_dstInlinePart, 1);
1266  break;
1267  default:
1268  break;
1269  }
1270  }
1271 
1272  return GetSerializedSize();
1273 }
1274 
1275 void
1277 {
1278  uint16_t field = tfField;
1279  m_baseFormat |= (field << 11);
1280 }
1281 
1284 {
1285  return TrafficClassFlowLabel_e((m_baseFormat >> 11) & 0x3);
1286 }
1287 
1288 void
1290 {
1291  uint16_t field = nhField;
1292  m_baseFormat |= (field << 10);
1293 }
1294 
1295 bool
1297 {
1298  return ((m_baseFormat >> 10) & 0x1);
1299 }
1300 
1301 void
1303 {
1304  uint16_t field = hlimField;
1305  m_baseFormat |= (field << 8);
1306 }
1307 
1310 {
1311  return Hlim_e((m_baseFormat >> 8) & 0x3);
1312 }
1313 
1314 void
1316 {
1317  uint16_t field = cidField;
1318  m_baseFormat |= (field << 7);
1319 }
1320 
1321 bool
1323 {
1324  return ((m_baseFormat >> 7) & 0x1);
1325 }
1326 
1327 void
1329 {
1330  uint16_t field = sacField;
1331  m_baseFormat |= (field << 6);
1332 }
1333 
1334 bool
1336 {
1337  return ((m_baseFormat >> 6) & 0x1);
1338 }
1339 
1340 void
1342 {
1343  uint16_t field = samField;
1344  m_baseFormat |= (field << 4);
1345 }
1346 
1349 {
1350  return HeaderCompression_e((m_baseFormat >> 4) & 0x3);
1351 }
1352 
1353 const uint8_t*
1355 {
1356  return m_srcInlinePart;
1357 }
1358 
1359 void
1360 SixLowPanIphc::SetSrcInlinePart(uint8_t srcInlinePart[16], uint8_t size)
1361 {
1362  NS_ASSERT_MSG(size <= 16, "Src inline part too large");
1363 
1364  memcpy(m_srcInlinePart, srcInlinePart, size);
1365 }
1366 
1367 void
1369 {
1370  uint16_t field = mField;
1371  m_baseFormat |= (field << 3);
1372 }
1373 
1374 bool
1376 {
1377  return ((m_baseFormat >> 3) & 0x1);
1378 }
1379 
1380 void
1382 {
1383  uint16_t field = dacField;
1384  m_baseFormat |= (field << 2);
1385 }
1386 
1387 bool
1389 {
1390  return ((m_baseFormat >> 2) & 0x1);
1391 }
1392 
1393 void
1395 {
1396  uint16_t field = damField;
1397  m_baseFormat |= field;
1398 }
1399 
1402 {
1403  return HeaderCompression_e(m_baseFormat & 0x3);
1404 }
1405 
1406 const uint8_t*
1408 {
1409  return m_dstInlinePart;
1410 }
1411 
1412 void
1413 SixLowPanIphc::SetDstInlinePart(uint8_t dstInlinePart[16], uint8_t size)
1414 {
1415  NS_ASSERT_MSG(size <= 16, "Dst inline part too large");
1416 
1417  memcpy(m_dstInlinePart, dstInlinePart, size);
1418 }
1419 
1420 void
1421 SixLowPanIphc::SetSrcContextId(uint8_t srcContextId)
1422 {
1423  NS_ASSERT_MSG(srcContextId < 16, "Src Context ID too large");
1424  m_srcdstContextId |= srcContextId << 4;
1425 }
1426 
1427 uint8_t
1429 {
1430  return (m_srcdstContextId >> 4);
1431 }
1432 
1433 void
1434 SixLowPanIphc::SetDstContextId(uint8_t dstContextId)
1435 {
1436  NS_ASSERT_MSG(dstContextId < 16, "Dst Context ID too large");
1437  m_srcdstContextId |= (dstContextId & 0xF);
1438 }
1439 
1440 uint8_t
1442 {
1443  return (m_srcdstContextId & 0xF);
1444 }
1445 
1446 void
1448 {
1449  NS_ASSERT_MSG(ecn < 4, "ECN too large");
1450  m_ecn = ecn;
1451 }
1452 
1453 uint8_t
1455 {
1456  return m_ecn;
1457 }
1458 
1459 void
1461 {
1462  NS_ASSERT_MSG(dscp < 64, "DSCP too large");
1463  m_dscp = dscp;
1464 }
1465 
1466 uint8_t
1468 {
1469  return m_dscp;
1470 }
1471 
1472 void
1473 SixLowPanIphc::SetFlowLabel(uint32_t flowLabel)
1474 {
1475  NS_ASSERT_MSG(flowLabel < 0x100000, "Flow Label too large");
1476  m_flowLabel = flowLabel;
1477 }
1478 
1479 uint32_t
1481 {
1482  return m_flowLabel;
1483 }
1484 
1485 void
1486 SixLowPanIphc::SetNextHeader(uint8_t nextHeader)
1487 {
1488  m_nextHeader = nextHeader;
1489 }
1490 
1491 uint8_t
1493 {
1494  return m_nextHeader;
1495 }
1496 
1497 void
1499 {
1500  m_hopLimit = hopLimit;
1501 }
1502 
1503 uint8_t
1505 {
1506  return m_hopLimit;
1507 }
1508 
1509 std::ostream&
1510 operator<<(std::ostream& os, const SixLowPanIphc& h)
1511 {
1512  h.Print(os);
1513  return os;
1514 }
1515 
1516 /*
1517  * SixLowPanNhcExtensionHeader
1518  */
1519 NS_OBJECT_ENSURE_REGISTERED(SixLowPanNhcExtension);
1520 
1522 {
1523  // 1110 xxxx
1524  m_nhcExtensionHeader = 0xE0;
1525  m_nhcNextHeader = 0;
1526  m_nhcBlobLength = 0;
1527 }
1528 
1529 TypeId
1531 {
1532  static TypeId tid = TypeId("ns3::SixLowPanNhcExtension")
1533  .SetParent<Header>()
1534  .SetGroupName("SixLowPan")
1535  .AddConstructor<SixLowPanNhcExtension>();
1536  return tid;
1537 }
1538 
1539 TypeId
1541 {
1542  return GetTypeId();
1543 }
1544 
1545 void
1546 SixLowPanNhcExtension::Print(std::ostream& os) const
1547 {
1548  os << "Compression kind: " << +m_nhcExtensionHeader << " Size: " << GetSerializedSize();
1549 }
1550 
1551 uint32_t
1553 {
1554  uint32_t serializedSize = 2;
1555  if (!GetNh())
1556  {
1557  serializedSize++;
1558  }
1559  return serializedSize + m_nhcBlobLength;
1560 }
1561 
1562 void
1564 {
1565  Buffer::Iterator i = start;
1567  if (!GetNh())
1568  {
1570  }
1573 }
1574 
1575 uint32_t
1577 {
1578  Buffer::Iterator i = start;
1580  if (!GetNh())
1581  {
1582  m_nhcNextHeader = i.ReadU8();
1583  }
1584  m_nhcBlobLength = i.ReadU8();
1586 
1587  return GetSerializedSize();
1588 }
1589 
1592 {
1594 }
1595 
1596 void
1598 {
1599  uint8_t field = extensionHeaderType;
1600  m_nhcExtensionHeader |= (field << 1);
1601 }
1602 
1605 {
1606  return Eid_e((m_nhcExtensionHeader >> 1) & 0x7);
1607 }
1608 
1609 void
1611 {
1612  m_nhcNextHeader = nextHeader;
1613 }
1614 
1615 uint8_t
1617 {
1618  return m_nhcNextHeader;
1619 }
1620 
1621 void
1623 {
1624  uint8_t field = nhField;
1625  m_nhcExtensionHeader |= field;
1626 }
1627 
1628 bool
1630 {
1631  return m_nhcExtensionHeader & 0x01;
1632 }
1633 
1634 void
1635 SixLowPanNhcExtension::SetBlob(const uint8_t* blob, uint32_t size)
1636 {
1637  NS_ASSERT_MSG(size < 255, "Buffer too long");
1638 
1639  m_nhcBlobLength = size;
1640  std::memcpy(m_nhcBlob, blob, size);
1641 }
1642 
1643 uint32_t
1644 SixLowPanNhcExtension::CopyBlob(uint8_t* blob, uint32_t size) const
1645 {
1646  NS_ASSERT_MSG(size > m_nhcBlobLength, "Buffer too short");
1647 
1648  std::memcpy(blob, m_nhcBlob, m_nhcBlobLength);
1649  return m_nhcBlobLength;
1650 }
1651 
1652 std::ostream&
1653 operator<<(std::ostream& os, const SixLowPanNhcExtension& h)
1654 {
1655  h.Print(os);
1656  return os;
1657 }
1658 
1659 /*
1660  * SixLowPanUdpNhcExtension
1661  */
1662 NS_OBJECT_ENSURE_REGISTERED(SixLowPanUdpNhcExtension);
1663 
1665 {
1666  // 1111 0xxx
1667  m_baseFormat = 0xF0;
1668  m_checksum = 0;
1669  m_srcPort = 0;
1670  m_dstPort = 0;
1671 }
1672 
1673 TypeId
1675 {
1676  static TypeId tid = TypeId("ns3::SixLowPanUdpNhcExtension")
1677  .SetParent<Header>()
1678  .SetGroupName("SixLowPan")
1679  .AddConstructor<SixLowPanUdpNhcExtension>();
1680  return tid;
1681 }
1682 
1683 TypeId
1685 {
1686  return GetTypeId();
1687 }
1688 
1689 void
1690 SixLowPanUdpNhcExtension::Print(std::ostream& os) const
1691 {
1692  os << "Compression kind: " << +m_baseFormat;
1693 }
1694 
1695 uint32_t
1697 {
1698  uint32_t serializedSize = 1;
1699  if (!GetC())
1700  {
1701  serializedSize += 2;
1702  }
1703  switch (GetPorts())
1704  {
1705  case PORTS_INLINE:
1706  serializedSize += 4;
1707  break;
1710  serializedSize += 3;
1711  break;
1713  serializedSize += 1;
1714  break;
1715  default:
1716  break;
1717  }
1718  return serializedSize;
1719 }
1720 
1721 void
1723 {
1724  Buffer::Iterator i = start;
1725  i.WriteU8(m_baseFormat);
1726  uint8_t temp;
1727 
1728  // Ports
1729  switch (GetPorts())
1730  {
1731  case PORTS_INLINE:
1734  break;
1737  i.WriteU8(m_dstPort & 0xff);
1738  break;
1740  i.WriteU8(m_srcPort & 0xff);
1742  break;
1744  temp = ((m_srcPort & 0xf) << 4) | (m_dstPort & 0xf);
1745  i.WriteU8(temp);
1746  break;
1747  default:
1748  break;
1749  }
1750 
1751  // Checksum
1752  if (!GetC())
1753  {
1754  i.WriteU16(m_checksum);
1755  }
1756 }
1757 
1758 uint32_t
1760 {
1761  Buffer::Iterator i = start;
1762  m_baseFormat = i.ReadU8();
1763  uint8_t temp;
1764 
1765  // Ports
1766  switch (GetPorts())
1767  {
1768  case PORTS_INLINE:
1769  m_srcPort = i.ReadNtohU16();
1770  m_dstPort = i.ReadNtohU16();
1771  break;
1773  m_srcPort = i.ReadNtohU16();
1774  m_dstPort = i.ReadU8();
1775  break;
1777  m_srcPort = i.ReadU8();
1778  m_dstPort = i.ReadNtohU16();
1779  break;
1781  temp = i.ReadU8();
1782  m_srcPort = temp >> 4;
1783  m_dstPort = temp & 0xf;
1784  break;
1785  default:
1786  break;
1787  }
1788 
1789  // Checksum
1790  if (!GetC())
1791  {
1792  m_checksum = i.ReadU16();
1793  }
1794 
1795  return GetSerializedSize();
1796 }
1797 
1800 {
1802 }
1803 
1804 void
1806 {
1807  uint16_t field = ports;
1808  m_baseFormat |= field;
1809 }
1810 
1813 {
1814  return Ports_e(m_baseFormat & 0x3);
1815 }
1816 
1817 void
1819 {
1820  m_srcPort = srcport;
1821 }
1822 
1823 uint16_t
1825 {
1826  return m_srcPort;
1827 }
1828 
1829 void
1831 {
1832  m_dstPort = dstport;
1833 }
1834 
1835 uint16_t
1837 {
1838  return m_dstPort;
1839 }
1840 
1841 void
1843 {
1844  uint16_t field = cField;
1845  m_baseFormat |= (field << 2);
1846 }
1847 
1848 bool
1850 {
1851  return ((m_baseFormat >> 2) & 0x1);
1852 }
1853 
1854 void
1856 {
1857  m_checksum = checksum;
1858 }
1859 
1860 uint16_t
1862 {
1863  return m_checksum;
1864 }
1865 
1866 std::ostream&
1867 operator<<(std::ostream& os, const SixLowPanUdpNhcExtension& h)
1868 {
1869  h.Print(os);
1870  return os;
1871 }
1872 
1873 /*
1874  * SixLowPanBc0
1875  */
1876 NS_OBJECT_ENSURE_REGISTERED(SixLowPanBc0);
1877 
1879 {
1880  m_seqNumber = 66;
1881 }
1882 
1883 TypeId
1885 {
1886  static TypeId tid = TypeId("ns3::SixLowPanBc0")
1887  .SetParent<Header>()
1888  .SetGroupName("SixLowPan")
1889  .AddConstructor<SixLowPanBc0>();
1890  return tid;
1891 }
1892 
1893 TypeId
1895 {
1896  return GetTypeId();
1897 }
1898 
1899 void
1900 SixLowPanBc0::Print(std::ostream& os) const
1901 {
1902  os << "Sequence number: " << +m_seqNumber;
1903 }
1904 
1905 uint32_t
1907 {
1908  return 2;
1909 }
1910 
1911 void
1913 {
1914  Buffer::Iterator i = start;
1915  i.WriteU8(0x50);
1916  i.WriteU8(m_seqNumber);
1917 }
1918 
1919 uint32_t
1921 {
1922  Buffer::Iterator i = start;
1923  uint8_t dispatch = i.ReadU8();
1924 
1925  if (dispatch != 0x50)
1926  {
1927  return 0;
1928  }
1929 
1930  m_seqNumber = i.ReadU8();
1931 
1932  return GetSerializedSize();
1933 }
1934 
1935 void
1937 {
1938  m_seqNumber = seqNumber;
1939 }
1940 
1941 uint8_t
1943 {
1944  return m_seqNumber;
1945 }
1946 
1947 std::ostream&
1948 operator<<(std::ostream& os, const SixLowPanBc0& h)
1949 {
1950  h.Print(os);
1951  return os;
1952 }
1953 
1954 /*
1955  * SixLowPanMesh
1956  */
1957 NS_OBJECT_ENSURE_REGISTERED(SixLowPanMesh);
1958 
1960 {
1961  m_hopsLeft = 0;
1962  m_src = Address();
1963  m_dst = Address();
1964  m_v = false;
1965  m_f = false;
1966 }
1967 
1968 TypeId
1970 {
1971  static TypeId tid = TypeId("ns3::SixLowPanMesh")
1972  .SetParent<Header>()
1973  .SetGroupName("SixLowPan")
1974  .AddConstructor<SixLowPanMesh>();
1975  return tid;
1976 }
1977 
1978 TypeId
1980 {
1981  return GetTypeId();
1982 }
1983 
1984 void
1985 SixLowPanMesh::Print(std::ostream& os) const
1986 {
1987  os << "Hops left: " << +m_hopsLeft << ", src: ";
1989  {
1991  }
1992  else
1993  {
1995  }
1996  os << ", dst: ";
1998  {
2000  }
2001  else
2002  {
2004  }
2005 }
2006 
2007 uint32_t
2009 {
2010  uint32_t serializedSize = 1;
2011 
2012  if (m_hopsLeft >= 0xF)
2013  {
2014  serializedSize++;
2015  }
2016 
2017  if (m_v)
2018  {
2019  serializedSize += 2;
2020  }
2021  else
2022  {
2023  serializedSize += 8;
2024  }
2025 
2026  if (m_f)
2027  {
2028  serializedSize += 2;
2029  }
2030  else
2031  {
2032  serializedSize += 8;
2033  }
2034 
2035  return serializedSize;
2036 }
2037 
2038 void
2040 {
2041  Buffer::Iterator i = start;
2042 
2043  uint8_t dispatch = 0x80;
2044 
2045  if (m_v)
2046  {
2047  dispatch |= 0x20;
2048  }
2049  if (m_f)
2050  {
2051  dispatch |= 0x10;
2052  }
2053 
2054  if (m_hopsLeft < 0xF)
2055  {
2056  dispatch |= m_hopsLeft;
2057  i.WriteU8(dispatch);
2058  }
2059  else
2060  {
2061  dispatch |= 0xF;
2062  i.WriteU8(dispatch);
2063  i.WriteU8(m_hopsLeft);
2064  }
2065 
2066  uint8_t buffer[8];
2067 
2068  m_src.CopyTo(buffer);
2069  if (m_v)
2070  {
2071  i.Write(buffer, 2);
2072  }
2073  else
2074  {
2075  i.Write(buffer, 8);
2076  }
2077 
2078  m_dst.CopyTo(buffer);
2079  if (m_f)
2080  {
2081  i.Write(buffer, 2);
2082  }
2083  else
2084  {
2085  i.Write(buffer, 8);
2086  }
2087 }
2088 
2089 uint32_t
2091 {
2092  Buffer::Iterator i = start;
2093  uint8_t temp = i.ReadU8();
2094 
2095  if ((temp & 0xC0) != 0x80)
2096  {
2097  return 0;
2098  }
2099 
2100  m_v = temp & 0x20;
2101  m_f = temp & 0x10;
2102  m_hopsLeft = temp & 0xF;
2103 
2104  if (m_hopsLeft == 0xF)
2105  {
2106  m_hopsLeft = i.ReadU8();
2107  }
2108 
2109  uint8_t buffer[8];
2110  uint8_t addrSize;
2111 
2112  if (m_v)
2113  {
2114  addrSize = 2;
2115  }
2116  else
2117  {
2118  addrSize = 8;
2119  }
2120  i.Read(buffer, addrSize);
2121  m_src.CopyFrom(buffer, addrSize);
2122 
2123  if (m_f)
2124  {
2125  addrSize = 2;
2126  }
2127  else
2128  {
2129  addrSize = 8;
2130  }
2131  i.Read(buffer, addrSize);
2132  m_dst.CopyFrom(buffer, addrSize);
2133 
2134  return GetSerializedSize();
2135 }
2136 
2137 void
2139 {
2140  if (Mac64Address::IsMatchingType(originator))
2141  {
2142  m_v = false;
2143  }
2144  else if (Mac16Address::IsMatchingType(originator))
2145  {
2146  m_v = true;
2147  }
2148  else
2149  {
2150  NS_ABORT_MSG("SixLowPanMesh::SetOriginator - incompatible address");
2151  }
2152 
2153  m_src = originator;
2154 }
2155 
2156 Address
2158 {
2159  return m_src;
2160 }
2161 
2162 void
2164 {
2165  if (Mac64Address::IsMatchingType(finalDst))
2166  {
2167  m_f = false;
2168  }
2169  else if (Mac16Address::IsMatchingType(finalDst))
2170  {
2171  m_f = true;
2172  }
2173  else
2174  {
2175  NS_ABORT_MSG("SixLowPanMesh::SetFinalDst - incompatible address");
2176  }
2177 
2178  m_dst = finalDst;
2179 }
2180 
2181 Address
2183 {
2184  return m_dst;
2185 }
2186 
2187 void
2189 {
2190  m_hopsLeft = hopsLeft;
2191 }
2192 
2193 uint8_t
2195 {
2196  return m_hopsLeft;
2197 }
2198 
2199 std::ostream&
2200 operator<<(std::ostream& os, const SixLowPanMesh& h)
2201 {
2202  h.Print(os);
2203  return os;
2204 }
2205 
2206 } // namespace ns3
a polymophic address class
Definition: address.h:101
uint32_t CopyFrom(const uint8_t *buffer, uint8_t len)
Definition: address.cc:106
uint32_t CopyTo(uint8_t buffer[MAX_SIZE]) const
Copy the address bytes into a buffer.
Definition: address.cc:86
iterator in a Buffer instance
Definition: buffer.h:100
uint8_t ReadU8()
Definition: buffer.h:1027
void WriteU8(uint8_t data)
Definition: buffer.h:881
void Write(const uint8_t *buffer, uint32_t size)
Definition: buffer.cc:948
void WriteU16(uint16_t data)
Definition: buffer.cc:859
void Read(uint8_t *buffer, uint32_t size)
Definition: buffer.cc:1125
void WriteHtonU16(uint16_t data)
Definition: buffer.h:915
uint16_t ReadNtohU16()
Definition: buffer.h:954
uint16_t ReadU16()
Definition: buffer.h:1035
Protocol header serialization and deserialization.
Definition: header.h:44
virtual uint32_t Deserialize(Buffer::Iterator start)=0
Deserialize the object from a buffer iterator.
static bool IsMatchingType(const Address &address)
static Mac16Address ConvertFrom(const Address &address)
static bool IsMatchingType(const Address &address)
static Mac64Address ConvertFrom(const Address &address)
6LoWPAN BC0 header - see RFC 4944.
void Print(std::ostream &os) const override
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
TypeId GetInstanceTypeId() const override
Return the instance type identifier.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
void SetSequenceNumber(uint8_t seqNumber)
Set the "Sequence Number" field.
static TypeId GetTypeId()
Get the type ID.
uint8_t m_seqNumber
Sequence number.
uint8_t GetSequenceNumber() const
Get the "Sequence Number" field.
static Dispatch_e GetDispatchType(uint8_t dispatch)
Get the Dispatch type.
static NhcDispatch_e GetNhcDispatchType(uint8_t dispatch)
Get the NhcDispatch type.
NhcDispatch_e
Dispatch values for Next Header compression.
6LoWPAN FRAG1 header - see RFC 4944.
TypeId GetInstanceTypeId() const override
Return the instance type identifier.
static TypeId GetTypeId()
Get the type ID.
void SetDatagramSize(uint16_t datagramSize)
Set the datagram size.
void Print(std::ostream &os) const override
void SetDatagramTag(uint16_t datagramTag)
Set the datagram tag.
uint16_t GetDatagramSize() const
Get the datagram size.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
uint16_t m_datagramTag
Datagram tag.
uint16_t GetDatagramTag() const
Get the datagram tag.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
uint16_t m_datagramSize
Datagram size.
6LoWPAN FRAGN header - see RFC 4944.
TypeId GetInstanceTypeId() const override
Return the instance type identifier.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
uint16_t m_datagramTag
Datagram tag.
void SetDatagramSize(uint16_t datagramSize)
Set the datagram size.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
static TypeId GetTypeId()
Get the type ID.
uint16_t GetDatagramTag() const
Get the datagram tag.
void SetDatagramTag(uint16_t datagramTag)
Set the datagram tag.
void SetDatagramOffset(uint8_t datagramOffset)
Set the datagram offset.
uint8_t GetDatagramOffset() const
Get the datagram offset.
uint8_t m_datagramOffset
Datagram offset.
uint16_t GetDatagramSize() const
Get the datagram size.
uint16_t m_datagramSize
Datagram size.
void Print(std::ostream &os) const override
6LoWPAN HC1 header - see RFC 4944.
static TypeId GetTypeId()
Get the type ID.
void SetTcflCompression(bool tcflCompression)
Set the Traffic Class and Flow Labels as compressed.
uint8_t m_dstInterface[8]
Destination interface.
uint8_t GetHopLimit() const
Get the "Hop limit" field (TTL).
const uint8_t * GetSrcPrefix() const
Get the source prefix.
void SetFlowLabel(uint32_t flowLabel)
Set the Flow Label value.
uint8_t GetTrafficClass() const
Get the Traffic Class value.
void SetDstCompression(LowPanHc1Addr_e dstCompression)
Set Destination Compression type.
void SetTrafficClass(uint8_t trafficClass)
Set the Traffic Class value.
TypeId GetInstanceTypeId() const override
Return the instance type identifier.
void SetHopLimit(uint8_t limit)
Set the "Hop limit" field (TTL).
LowPanHc1Addr_e
Kind of address compression.
uint8_t m_srcInterface[8]
Source interface.
uint8_t m_dstPrefix[8]
Destination prefix.
uint32_t GetFlowLabel() const
Get the Flow Label value.
bool m_hc2HeaderPresent
Is next header HC2 compressed.
const uint8_t * GetSrcInterface() const
Get the source interface.
const uint8_t * GetDstPrefix() const
Get the destination prefix.
void SetHc2HeaderPresent(bool hc2HeaderPresent)
Set the next header a HC2 compressed header.
LowPanHc1NextHeader_e m_nextHeaderCompression
Next header compression.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
bool m_tcflCompression
Is TC and FL compressed.
uint32_t m_flowLabel
Flow Label.
void SetNextHeader(uint8_t nextHeader)
Set the Next Header value.
LowPanHc1Addr_e m_dstCompression
Destination compression type.
LowPanHc1NextHeader_e
Next header information.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
uint8_t m_hopLimit
Hop Limit.
void SetSrcCompression(LowPanHc1Addr_e srcCompression)
Set Source Compression type.
uint8_t m_srcPrefix[8]
Source prefix.
void SetDstInterface(const uint8_t *dstInterface)
Set the destination interface.
void SetDstPrefix(const uint8_t *dstPrefix)
Set the destination prefix.
const uint8_t * GetDstInterface() const
Get the destination interface.
LowPanHc1Addr_e m_srcCompression
Source compression type.
uint8_t m_nextHeader
Next header.
void Print(std::ostream &os) const override
void SetSrcPrefix(const uint8_t *srcPrefix)
Set the source prefix.
uint8_t GetNextHeader() const
Get the Next Header value.
void SetSrcInterface(const uint8_t *srcInterface)
Set the source interface.
uint8_t m_trafficClass
Traffic Class.
LowPanHc1Addr_e GetDstCompression() const
Get Destination Compression type.
bool IsHc2HeaderPresent() const
Check if there is a HC2 compressed header.
LowPanHc1Addr_e GetSrcCompression() const
Get Source Compression type.
bool IsTcflCompression() const
Check if the Traffic Class and Flow Labels are compressed.
LOWPAN_IPHC base Encoding - see RFC 6282.
bool GetSac() const
Get the SAC (Source Address Compression) compression.
void SetNextHeader(uint8_t nextHeader)
Set the Next Header field.
uint8_t GetNextHeader() const
Get the Next Header field.
void SetHlim(Hlim_e hlimField)
Set the HLIM (Hop Limit) compression.
void SetDstContextId(uint8_t dstContextId)
Set the DstContextId.
Hlim_e
HLIM: Hop Limit.
const uint8_t * GetSrcInlinePart() const
brief Get the source address inline part
uint8_t m_srcdstContextId
Src and Dst Context ID.
void SetSam(HeaderCompression_e samField)
Set the SAM (Source Address Mode) compression.
void SetNh(bool nhField)
Set the NH (Next Header) compression.
uint8_t GetDscp() const
Get the DSCP.
HeaderCompression_e
Source or Destination Address Mode.
HeaderCompression_e GetDam() const
Get the DAM (Destination Address Mode) compression.
uint8_t GetHopLimit() const
Get the Hop Limit field.
bool GetDac() const
Get the DAC (Destination Address Compression) compression.
uint8_t m_srcInlinePart[16]
source address inline part.
void SetEcn(uint8_t ecn)
Set the ECN (2bits).
uint8_t m_hopLimit
Hop Limit.
void SetFlowLabel(uint32_t flowLabel)
Set the Flow Label (20bits).
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
void SetDscp(uint8_t dscp)
Set the DSCP (6bits).
uint32_t GetFlowLabel() const
Get the Flow Label.
void SetTf(TrafficClassFlowLabel_e tfField)
Set the TF (Traffic Class, Flow Label) compression.
uint8_t GetEcn() const
Get the ECN.
static TypeId GetTypeId()
Get the type ID.
void SetDam(HeaderCompression_e damField)
Set the DAM (Destination Address Mode) compression.
void SetCid(bool cidField)
Set the CID (Context Identifier Extension) compression.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
Hlim_e GetHlim() const
Get the HLIM (Hop Limit) compression.
uint8_t m_dscp
DSCP bits.
void SetSac(bool sacField)
Set the SAC (Source Address Compression) compression.
bool GetNh() const
Get the NH (Next Header) compression.
void Print(std::ostream &os) const override
TrafficClassFlowLabel_e GetTf() const
Get the TF (Traffic Class, Flow Label) compression.
bool GetM() const
Get the M (Multicast) compression.
HeaderCompression_e GetSam() const
Get the SAM (Source Address Mode) compression.
uint8_t m_dstInlinePart[16]
destination address inline part.
TypeId GetInstanceTypeId() const override
Return the instance type identifier.
void SetDstInlinePart(uint8_t dstInlinePart[16], uint8_t size)
brief Set the destination address inline part
void SetSrcContextId(uint8_t srcContextId)
Set the SrcContextId.
void SetSrcInlinePart(uint8_t srcInlinePart[16], uint8_t size)
brief Set the source address inline part
TrafficClassFlowLabel_e
TF: Traffic Class, Flow Label.
void SetM(bool mField)
Set the M (Multicast) compression.
uint16_t m_baseFormat
Dispatch + encoding fields.
uint8_t m_nextHeader
Next header.
const uint8_t * GetDstInlinePart() const
brief Get the destination address inline part
bool GetCid() const
Get the CID (Context Identifier Extension) compression.
uint8_t GetSrcContextId() const
Get the SrcContextId.
uint32_t m_flowLabel
Flow Label bits.
void SetHopLimit(uint8_t hopLimit)
Set the Hop Limit field.
uint8_t m_ecn
ECN bits.
uint8_t GetDstContextId() const
Get the DstContextId.
void SetDac(bool dacField)
Set the DAC (Destination Address Compression) compression.
6LoWPAN IPv6 uncompressed header - see RFC 4944.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
static TypeId GetTypeId()
Get the type ID.
TypeId GetInstanceTypeId() const override
Return the instance type identifier.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
void Print(std::ostream &os) const override
6LoWPAN Mesh header - see RFC 4944.
bool m_f
True if Destination address is 16 bit.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
Address GetOriginator() const
Get the "Originator" address.
bool m_v
True if Originator address is 16 bit.
void SetHopsLeft(uint8_t hopsLeft)
Set the "Hops Left" field.
void SetFinalDst(Address finalDst)
Set the "Final Destination" address.
uint8_t m_hopsLeft
Hops left.
Address m_src
Originator (source) address.
TypeId GetInstanceTypeId() const override
Return the instance type identifier.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
uint8_t GetHopsLeft() const
Get the "Hops Left" field.
static TypeId GetTypeId()
Get the type ID.
void Print(std::ostream &os) const override
Address GetFinalDst() const
Get the "Final Destination" address.
void SetOriginator(Address originator)
Set the "Originator" address.
Address m_dst
Destination (final) address.
LOWPAN_NHC Extension Header Encoding - see RFC 6282.
uint8_t m_nhcNextHeader
Next header.
uint8_t m_nhcBlob[256]
NHC compressed header.
virtual SixLowPanDispatch::NhcDispatch_e GetNhcDispatchType() const
Get the NhcDispatch type.
TypeId GetInstanceTypeId() const override
Return the instance type identifier.
bool GetNh() const
Get the Next Header field value.
uint8_t m_nhcExtensionHeader
NHC extension header type.
Eid_e GetEid() const
Get the Extension Header Type.
void SetNh(bool nhField)
Set the NH field values.
void SetEid(Eid_e extensionHeaderType)
Set the Extension Header Type.
uint8_t m_nhcBlobLength
Length of the NHC compressed header.
void SetBlob(const uint8_t *blob, uint32_t size)
Set the option header data blob.
void Print(std::ostream &os) const override
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
Eid_e
EID: IPv6 Extension Header ID.
uint32_t CopyBlob(uint8_t *blob, uint32_t size) const
Get the option header data blob.
uint8_t GetNextHeader() const
Get the Next Header field value.
void SetNextHeader(uint8_t nextHeader)
Set the Next Header field values.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
static TypeId GetTypeId()
Get the type ID.
UDP LOWPAN_NHC Extension Header Encoding - see RFC 6282.
void Serialize(Buffer::Iterator start) const override
Serialize the packet.
TypeId GetInstanceTypeId() const override
Return the instance type identifier.
uint8_t m_baseFormat
Dispatch + encoding fields.
Ports_e GetPorts() const
Get the compressed Src and Dst Ports.
uint16_t GetChecksum() const
Get the Checksum field value.
uint16_t GetDstPort() const
Get the Destination Port.
void SetPorts(Ports_e port)
Set the compressed Src and Dst Ports.
bool GetC() const
Get the C (Checksum).
static TypeId GetTypeId()
Get the type ID.
void Print(std::ostream &os) const override
void SetChecksum(uint16_t checksum)
Set the Checksum field values.
void SetDstPort(uint16_t port)
Set the Destination Port.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
void SetSrcPort(uint16_t port)
Set the Source Port.
void SetC(bool cField)
Set the C (Checksum).
uint16_t m_dstPort
Destination port.
uint16_t m_srcPort
Source port.
virtual SixLowPanDispatch::NhcDispatch_e GetNhcDispatchType() const
Get the NhcDispatch type.
uint16_t GetSrcPort() const
Get the Source Port.
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
#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:86
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:159