A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
icmpv6-header.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007-2009 Strasbourg University
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: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
19  * Mehdi Benamor <benamor.mehdi@ensi.rnu.tn>
20  * David Gross <gdavid.devel@gmail.com>
21  */
22 
23 #include "ns3/assert.h"
24 #include "ns3/address-utils.h"
25 #include "ns3/log.h"
26 
27 #include "icmpv6-header.h"
28 
29 namespace ns3
30 {
31 
32 NS_OBJECT_ENSURE_REGISTERED (Icmpv6Header);
33 
34 NS_LOG_COMPONENT_DEFINE ("Icmpv6Header");
35 
37 {
38  static TypeId tid = TypeId ("ns3::Icmpv6Header")
39  .SetParent<Header> ()
40  .AddConstructor<Icmpv6Header> ()
41  ;
42  return tid;
43 }
44 
46 {
47  return GetTypeId ();
48 }
49 
51  : m_calcChecksum (true),
52  m_checksum (0),
53  m_type (0),
54  m_code (0)
55 {
56 }
57 
59 {
60 }
61 
62 uint8_t Icmpv6Header::GetType () const
63 {
64  return m_type;
65 }
66 
67 void Icmpv6Header::SetType (uint8_t type)
68 {
69  m_type = type;
70 }
71 
72 uint8_t Icmpv6Header::GetCode () const
73 {
74  return m_code;
75 }
76 
77 void Icmpv6Header::SetCode (uint8_t code)
78 {
79  m_code = code;
80 }
81 
82 uint16_t Icmpv6Header::GetChecksum () const
83 {
84  return m_checksum;
85 }
86 
87 void Icmpv6Header::SetChecksum (uint16_t checksum)
88 {
89  m_checksum = checksum;
90 }
91 
92 void Icmpv6Header::Print (std::ostream& os) const
93 {
94  os << "( type = " << (uint32_t)m_type << " code = " << (uint32_t)m_code << " checksum = " << (uint32_t)m_checksum << ")";
95 }
96 
98 {
99  return 4;
100 }
101 
103 {
105 
106  m_type = i.ReadU8 ();
107  m_code = i.ReadU8 ();
108  m_checksum = i.ReadNtohU16 ();
109 #if 0
110  i.ReadU32 (); /* padding */
111 #endif
112  return GetSerializedSize ();
113 }
114 
116 {
118 
119  i.WriteU8 (m_type);
120  i.WriteU8 (m_code);
121  i.WriteU16 (0);
122 #if 0
123  i.WriteU32 (0); /* padding */
124 #endif
125 
126  if (m_calcChecksum)
127  {
128  i = start;
129  uint16_t checksum = i.CalculateIpChecksum (i.GetSize (), m_checksum);
130  i = start;
131  i.Next (2);
132  i.WriteU16 (checksum);
133  }
134 }
135 
136 void Icmpv6Header::CalculatePseudoHeaderChecksum (Ipv6Address src, Ipv6Address dst, uint16_t length, uint8_t protocol)
137 {
138  Buffer buf = Buffer (40);
139  uint8_t tmp[16];
140  Buffer::Iterator it;
141 
142  buf.AddAtStart (40);
143  it = buf.Begin ();
144 
145  src.Serialize (tmp);
146  it.Write (tmp, 16); /* source IPv6 address */
147  dst.Serialize (tmp);
148  it.Write (tmp, 16); /* destination IPv6 address */
149  it.WriteU16 (0); /* length */
150  it.WriteU8 (length >> 8); /* length */
151  it.WriteU8 (length & 0xff); /* length */
152  it.WriteU16 (0); /* zero */
153  it.WriteU8 (0); /* zero */
154  it.WriteU8 (protocol); /* next header */
155 
156  it = buf.Begin ();
157  m_checksum = ~(it.CalculateIpChecksum (40));
158 }
159 
161 
163 {
165  SetCode (0);
166  SetReserved (0);
167  m_checksum = 0;
168 }
169 
171 {
172  static TypeId tid = TypeId ("ns3::Icmpv6NS")
174  .AddConstructor<Icmpv6NS> ()
175  ;
176  return tid;
177 }
178 
180 {
181  return GetTypeId ();
182 }
183 
185 {
187  SetCode (0);
188  SetReserved (0);
189  SetIpv6Target (target);
190  m_checksum = 0;
191 
192  /* test */
193  /*
194  m_reserved = 0xdeadbeef;
195  */
196 }
197 
199 {
200 }
201 
202 uint32_t Icmpv6NS::GetReserved () const
203 {
204  return m_reserved;
205 }
206 
207 void Icmpv6NS::SetReserved (uint32_t reserved)
208 {
209  m_reserved = reserved;
210 }
211 
213 {
214  return m_target;
215 }
216 
218 {
219  m_target = target;
220 }
221 
222 void Icmpv6NS::Print (std::ostream& os) const
223 {
224  os << "( type = " << (uint32_t)GetType () << " (NS) code = " << (uint32_t)GetCode () << " checksum = " << (uint32_t)GetChecksum () << ")";
225 }
226 
228 {
229  return 24;
230 }
231 
233 {
235  uint8_t buff_target[16];
236  uint16_t checksum = 0;
238 
239  i.WriteU8 (GetType ());
240  i.WriteU8 (GetCode ());
241  i.WriteU16 (0);
243  m_target.Serialize (buff_target);
244  i.Write (buff_target, 16);
245 
246  if (m_calcChecksum)
247  {
248  i = start;
249  checksum = i.CalculateIpChecksum (i.GetSize (), m_checksum);
250  i = start;
251  i.Next (2);
252  i.WriteU16 (checksum);
253  }
254 }
255 
257 {
258  uint8_t buf[16];
260 
261  SetType (i.ReadU8 ());
262  SetCode (i.ReadU8 ());
263  m_checksum = i.ReadU16 ();
264  m_reserved = i.ReadNtohU32 ();
265  i.Read (buf, 16);
266  m_target.Set (buf);
267 
268  return GetSerializedSize ();
269 }
270 
272 
274 {
275  static TypeId tid = TypeId ("ns3::Icmpv6NA")
277  .AddConstructor<Icmpv6NA> ()
278  ;
279  return tid;
280 }
281 
283 {
284  return GetTypeId ();
285 }
286 
288 {
290  SetCode (0);
291  SetReserved (0);
292  SetFlagR (0);
293  SetFlagS (0);
294  SetFlagO (0);
295  m_checksum = 0;
296 }
297 
299 {
300 }
301 
302 uint32_t Icmpv6NA::GetReserved () const
303 {
304  return m_reserved;
305 }
306 
307 void Icmpv6NA::SetReserved (uint32_t reserved)
308 {
309  m_reserved = reserved;
310 }
311 
313 {
314  return m_target;
315 }
316 
317 bool Icmpv6NA::GetFlagR () const
318 {
319  return m_flagR;
320 }
321 
322 void Icmpv6NA::SetFlagR (bool r)
323 {
324  m_flagR = r;
325 }
326 
327 bool Icmpv6NA::GetFlagS () const
328 {
329  return m_flagS;
330 }
331 
332 void Icmpv6NA::SetFlagS (bool s)
333 {
334  m_flagS = s;
335 }
336 
337 bool Icmpv6NA::GetFlagO () const
338 {
339  return m_flagO;
340 }
341 
342 void Icmpv6NA::SetFlagO (bool o)
343 {
344  m_flagO = o;
345 }
346 
348 {
349  m_target = target;
350 }
351 
352 void Icmpv6NA::Print (std::ostream& os) const
353 {
354  os << "( type = " << (uint32_t)GetType () << " (NA) code = " << (uint32_t)GetCode () << " checksum = " << (uint32_t)GetChecksum () << ")";
355 }
356 
358 {
359  return 24;
360 }
361 
363 {
364  uint8_t buff_target[16];
365  uint16_t checksum = 0;
367  uint32_t reserved = m_reserved;
368 
369  i.WriteU8 (GetType ());
370  i.WriteU8 (GetCode ());
371  i.WriteU16 (0);
372 
373  if (m_flagR)
374  {
375  reserved |= (uint32_t)(1 << 31);
376  }
377 
378  if (m_flagS)
379  {
380  reserved |= (uint32_t)(1<< 30);
381  }
382 
383  if (m_flagO)
384  {
385  reserved |= (uint32_t)(1<< 29);
386  }
387 
388  i.WriteHtonU32 (reserved);
389  m_target.Serialize (buff_target);
390  i.Write (buff_target, 16);
391 
392  if (m_calcChecksum)
393  {
394  i = start;
395  checksum = i.CalculateIpChecksum (i.GetSize (), GetChecksum ());
396  i = start;
397  i.Next (2);
398  i.WriteU16 (checksum);
399  }
400 }
401 
403 {
404  uint8_t buf[16];
406 
407  SetType (i.ReadU8 ());
408  SetCode (i.ReadU8 ());
409  m_checksum = i.ReadU16 ();
410  m_reserved = i.ReadNtohU32 ();
411 
412  m_flagR = false;
413  m_flagS = false;
414  m_flagO = false;
415 
416  if (m_reserved & (1 << 31))
417  {
418  m_flagR = true;
419  }
420 
421  if (m_reserved & (1 << 30))
422  {
423  m_flagS = true;
424  }
425 
426  if (m_reserved & (1 << 29))
427  {
428  m_flagO = true;
429  }
430 
431  i.Read (buf, 16);
432  m_target.Set (buf);
433 
434  return GetSerializedSize ();
435 }
436 
438 
440 {
441  static TypeId tid = TypeId ("ns3::Icmpv6RA")
443  .AddConstructor<Icmpv6RA> ()
444  ;
445  return tid;
446 }
447 
449 {
450  return GetTypeId ();
451 }
452 
454 {
456  SetCode (0);
457  SetFlags (0);
458  SetFlagM (0);
459  SetFlagO (0);
460  SetFlagH (0);
461  SetCurHopLimit (0);
462  SetLifeTime (0);
464  SetReachableTime (0);
465 }
466 
468 {
469 }
470 
471 void Icmpv6RA::SetCurHopLimit (uint8_t m)
472 {
473  m_curHopLimit = m;
474 }
475 
476 uint8_t Icmpv6RA::GetCurHopLimit () const
477 {
478  return m_curHopLimit;
479 }
480 
481 uint16_t Icmpv6RA::GetLifeTime () const
482 {
483  return m_LifeTime;
484 }
485 
486 uint32_t Icmpv6RA::GetReachableTime () const
487 {
488  return m_ReachableTime;
489 }
490 
492 {
493  return m_RetransmissionTimer;
494 }
495 
496 void Icmpv6RA::SetLifeTime (uint16_t l)
497 {
498  m_LifeTime = l;
499 }
500 
501 void Icmpv6RA::SetReachableTime (uint32_t r)
502 {
503  m_ReachableTime = r;
504 }
505 
507 {
509 }
510 
511 bool Icmpv6RA::GetFlagM () const
512 {
513  return m_flagM;
514 }
515 
516 void Icmpv6RA::SetFlagM (bool m)
517 {
518  m_flagM = m;
519 }
520 
521 bool Icmpv6RA::GetFlagO () const
522 {
523  return m_flagO;
524 }
525 
526 void Icmpv6RA::SetFlagO (bool o)
527 {
528  m_flagO = o;
529 }
530 
531 bool Icmpv6RA::GetFlagH () const
532 {
533  return m_flagH;
534 }
535 
536 void Icmpv6RA::SetFlagH (bool h)
537 {
538  m_flagH = h;
539 }
540 
541 uint8_t Icmpv6RA::GetFlags () const
542 {
543  return m_flags;
544 }
545 
546 void Icmpv6RA::SetFlags (uint8_t f)
547 {
548  m_flags = f;
549 }
550 
551 void Icmpv6RA::Print (std::ostream& os) const
552 {
553  os << "( type = " << (uint32_t)GetType () << " (RA) code = " << (uint32_t)GetCode () << " checksum = " << (uint32_t)GetChecksum () << ")";
554 }
555 
557 {
558  return 16;
559 }
560 
562 {
563  uint16_t checksum = 0;
565  uint8_t flags = 0;
566 
567  i.WriteU8 (GetType ());
568  i.WriteU8 (GetCode ());
569  i.WriteHtonU16 (0);
571 
572  if (m_flagM)
573  {
574  flags |= (uint8_t)(1<< 7);
575  }
576 
577  if (m_flagO)
578  {
579  flags |= (uint8_t)(1<< 6);
580  }
581 
582  if (m_flagH)
583  {
584  flags |= (uint8_t)(1<< 5);
585  }
586  i.WriteU8 (flags);
587  i.WriteHtonU16 (GetLifeTime ());
590 
591  i = start;
592  checksum = i.CalculateIpChecksum (i.GetSize (), GetChecksum ());
593 
594  i = start;
595  i.Next (2);
596  i.WriteU16 (checksum);
597 }
598 
600 {
602 
603  SetType (i.ReadU8 ());
604  SetCode (i.ReadU8 ());
605  m_checksum = i.ReadU16 ();
606  SetCurHopLimit (i.ReadU8 ());
607  m_flags = i.ReadU8 ();
608  m_flagM = false;
609  m_flagO = false;
610  m_flagH = false;
611 
612  if (m_flags & (1 << 7))
613  {
614  m_flagM = true;
615  }
616 
617  if (m_flags & (1 << 6))
618  {
619  m_flagO = true;
620  }
621 
622  if (m_flags & (1 << 5))
623  {
624  m_flagH = true;
625  }
626  SetLifeTime (i.ReadNtohU16 ());
629 
630  return GetSerializedSize ();
631 }
632 
634 
636 {
637  static TypeId tid = TypeId ("ns3::Icmpv6RS")
639  .AddConstructor<Icmpv6RS> ()
640  ;
641  return tid;
642 }
643 
645 {
646  return GetTypeId ();
647 }
648 
650 {
652  SetCode (0);
653  SetReserved (0);
654 }
655 
657 {
658 }
659 
660 uint32_t Icmpv6RS::GetReserved () const
661 {
662  return m_reserved;
663 }
664 
665 void Icmpv6RS::SetReserved (uint32_t reserved)
666 {
667  m_reserved = reserved;
668 }
669 
670 void Icmpv6RS::Print (std::ostream& os) const
671 {
672  os << "( type = " << (uint32_t)GetType () << " (RS) code = " << (uint32_t)GetCode () << " checksum = " << (uint32_t)GetChecksum () << ")";
673 }
674 
676 {
677  return 8;
678 }
679 
681 {
683  uint16_t checksum = 0;
685 
686  i.WriteU8 (GetType ());
687  i.WriteU8 (GetCode ());
688  i.WriteU16 (0);
690 
691  if (m_calcChecksum)
692  {
693  i = start;
694  checksum = i.CalculateIpChecksum (i.GetSize (), GetChecksum ());
695 
696  i = start;
697  i.Next (2);
698  i.WriteU16 (checksum);
699  }
700 }
701 
703 {
706 
707  SetType (i.ReadU8 ());
708  SetCode (i.ReadU8 ());
709  m_checksum = i.ReadU16 ();
710  m_reserved = i.ReadNtohU32 ();
711 
712  return GetSerializedSize ();
713 }
714 
716 
718 {
719  static TypeId tid = TypeId ("ns3::Icmpv6Redirection")
721  .AddConstructor<Icmpv6Redirection> ()
722  ;
723  return tid;
724 }
725 
727 {
728  return GetTypeId ();
729 }
730 
732  : m_target (Ipv6Address ("")),
733  m_destination (Ipv6Address ("")),
734  m_reserved (0)
735 {
737  SetCode (0);
738  m_checksum = 0;
739 }
740 
742 {
743 }
744 
745 void Icmpv6Redirection::SetReserved (uint32_t reserved)
746 {
747  m_reserved = reserved;
748 }
749 
751 {
752  return m_reserved;
753 }
754 
756 {
757  return m_target;
758 }
759 
761 {
762  m_target = target;
763 }
764 
766 {
767  return m_destination;
768 }
769 
771 {
772  m_destination = destination;
773 }
774 
775 void Icmpv6Redirection::Print (std::ostream& os) const
776 {
777  os << "( type = " << (uint32_t)GetType () << " (Redirection) code = " << (uint32_t)GetCode () << " checksum = " << (uint32_t)GetChecksum () << " target = " << m_target << " destination = " << m_destination << ")";
778 }
779 
781 {
782  return 40;
783 }
784 
786 {
787  uint8_t buff[16];
788  uint16_t checksum = 0;
790 
791  i.WriteU8 (GetType ());
792  i.WriteU8 (GetCode ());
793  i.WriteU16 (checksum);
794  i.WriteU32 (m_reserved);
795 
796  m_target.Serialize (buff);
797  i.Write (buff, 16);
798 
799  m_destination.Serialize (buff);
800  i.Write (buff, 16);
801 
802  if (m_calcChecksum)
803  {
804  i = start;
805  checksum = i.CalculateIpChecksum (i.GetSize (), GetChecksum ());
806 
807  i = start;
808  i.Next (2);
809  i.WriteU16 (checksum);
810  }
811 }
812 
814 {
815  uint8_t buff[16];
817 
818  SetType (i.ReadU8 ());
819  SetCode (i.ReadU8 ());
820  m_checksum = i.ReadU16 ();
821  SetReserved (i.ReadU32 ());
822 
823  i.Read (buff, 16);
824  m_target.Set (buff);
825 
826  i.Read (buff, 16);
827  m_destination.Set (buff);
828 
829  return GetSerializedSize ();
830 }
831 
833 
835 {
836  static TypeId tid = TypeId ("ns3::Icmpv6Echo")
838  .AddConstructor<Icmpv6Echo> ()
839  ;
840  return tid;
841 }
842 
844 {
845  return GetTypeId ();
846 }
847 
849 {
851  SetCode (0);
852  m_checksum = 0;
853  SetId (0);
854  SetSeq (0);
855 }
856 
858 {
860  SetCode (0);
861  m_checksum = 0;
862  SetId (0);
863  SetSeq (0);
864 }
865 
867 {
868 }
869 
870 uint16_t Icmpv6Echo::GetId () const
871 {
872  return m_id;
873 }
874 
875 void Icmpv6Echo::SetId (uint16_t id)
876 {
877  m_id = id;
878 }
879 
880 uint16_t Icmpv6Echo::GetSeq () const
881 {
882  return m_seq;
883 }
884 
885 void Icmpv6Echo::SetSeq (uint16_t seq)
886 {
887  m_seq = seq;
888 }
889 
890 void Icmpv6Echo::Print (std::ostream& os) const
891 {
892  os << "( type = " << (GetType () == 128 ? "128 (Request)" : "129 (Reply)") <<
893  " code = " << (uint32_t)GetCode () <<
894  " checksum = " << (uint32_t)GetChecksum () << ")";
895 }
896 
898 {
899  return 8;
900 }
901 
903 {
904  uint16_t checksum = 0;
906 
907  i.WriteU8 (GetType ());
908  i.WriteU8 (GetCode ());
909  i.WriteHtonU16 (0);
910 
911  i.WriteHtonU16 (m_id);
912  i.WriteHtonU16 (m_seq);
913 
914  if (m_calcChecksum)
915  {
916  i = start;
917  checksum = i.CalculateIpChecksum (i.GetSize (), GetChecksum ());
918  i = start;
919  i.Next (2);
920  i.WriteU16 (checksum);
921  }
922 }
923 
925 {
927 
928  SetType (i.ReadU8 ());
929  SetCode (i.ReadU8 ());
930  m_checksum = i.ReadU16 ();
931 
932  m_id = i.ReadNtohU16 ();
933  m_seq = i.ReadNtohU16 ();
934  return GetSerializedSize ();
935 }
936 
938 
940 {
941  static TypeId tid = TypeId ("ns3::Icmpv6DestinationUnreachable")
943  .AddConstructor<Icmpv6DestinationUnreachable> ()
944  ;
945  return tid;
946 }
947 
949 {
950  return GetTypeId ();
951 }
952 
954  : m_packet (0)
955 {
957 }
958 
960 {
961 }
962 
964 {
965  return m_packet;
966 }
967 
969 {
970  NS_ASSERT (p->GetSize () <= 1280);
971  m_packet = p;
972 }
973 
974 void Icmpv6DestinationUnreachable::Print (std::ostream& os) const
975 {
976  os << "( type = " << (uint32_t)GetType () << " (Destination Unreachable) code = " << (uint32_t)GetCode () << " checksum = " << (uint32_t)GetChecksum () << ")";
977 }
978 
980 {
981  return 8 + m_packet->GetSize ();
982 }
983 
985 {
986  uint16_t checksum = 0;
988 
989  i.WriteU8 (GetType ());
990  i.WriteU8 (GetCode ());
991  i.WriteHtonU16 (0);
992  i.WriteHtonU32 (0);
993 
994  uint32_t size = m_packet->GetSize ();
995  uint8_t *buf = new uint8_t[size];
996  m_packet->CopyData (buf, size);
997  i.Write (buf, size);
998  delete[] buf;
999 
1000  i = start;
1001  checksum = i.CalculateIpChecksum (i.GetSize (), GetChecksum ());
1002 
1003  i = start;
1004  i.Next (2);
1005  i.WriteU16 (checksum);
1006 }
1007 
1009 {
1010  uint16_t length = start.GetSize () - 8;
1011  uint8_t* data = new uint8_t[length];
1012  Buffer::Iterator i = start;
1013 
1014  SetType (i.ReadU8 ());
1015  SetCode (i.ReadU8 ());
1016  m_checksum = i.ReadU16 ();
1017  i.ReadNtohU32 ();
1018  i.Read (data, length);
1019  m_packet = Create<Packet> (data, length);
1020 
1021  delete[] data;
1022  return GetSerializedSize ();
1023 }
1024 
1026 
1028 {
1029  static TypeId tid = TypeId ("ns3::Icmpv6TooBig")
1030  .SetParent<Icmpv6Header> ()
1031  .AddConstructor<Icmpv6TooBig> ()
1032  ;
1033  return tid;
1034 }
1035 
1037 {
1038  return GetTypeId ();
1039 }
1040 
1042  : m_packet (0),
1043  m_mtu (0)
1044 {
1046 }
1047 
1049 {
1050 }
1051 
1053 {
1054  return m_packet;
1055 }
1056 
1058 {
1059  NS_ASSERT (p->GetSize () <= 1280);
1060  m_packet = p;
1061 }
1062 
1063 uint32_t Icmpv6TooBig::GetMtu () const
1064 {
1065  return m_mtu;
1066 }
1067 
1068 void Icmpv6TooBig::SetMtu (uint32_t mtu)
1069 {
1070  m_mtu = mtu;
1071 }
1072 
1073 void Icmpv6TooBig::Print (std::ostream& os) const
1074 {
1075  os << "( type = " << (uint32_t)GetType () << " (Too Big) code = " << (uint32_t)GetCode () << " checksum = " << (uint32_t)GetChecksum () << " mtu = " << (uint32_t)GetMtu () << ")";
1076 }
1077 
1079 {
1080  return 8 + m_packet->GetSize ();
1081 }
1082 
1084 {
1085  uint16_t checksum = 0;
1086  Buffer::Iterator i = start;
1087 
1088  i.WriteU8 (GetType ());
1089  i.WriteU8 (GetCode ());
1090  i.WriteHtonU16 (0);
1091  i.WriteHtonU32 (GetMtu ());
1092 
1093  uint32_t size = m_packet->GetSize ();
1094  uint8_t *buf = new uint8_t[size];
1095  m_packet->CopyData (buf, size);
1096  i.Write (buf, size);
1097  delete[] buf;
1098 
1099  i = start;
1100  checksum = i.CalculateIpChecksum (i.GetSize (), GetChecksum ());
1101 
1102  i = start;
1103  i.Next (2);
1104  i.WriteU16 (checksum);
1105 }
1106 
1108 {
1109  uint16_t length = start.GetSize () - 8;
1110  uint8_t* data = new uint8_t[length];
1111  Buffer::Iterator i = start;
1112 
1113  SetType (i.ReadU8 ());
1114  SetCode (i.ReadU8 ());
1115  m_checksum = i.ReadU16 ();
1116  SetMtu (i.ReadNtohU32 ());
1117  i.Read (data, length);
1118  m_packet = Create<Packet> (data, length);
1119 
1120  delete[] data;
1121  return GetSerializedSize ();
1122 }
1123 
1125 
1127 {
1128  static TypeId tid = TypeId ("ns3::Icmpv6TimeExceeded")
1129  .SetParent<Icmpv6Header> ()
1130  .AddConstructor<Icmpv6TimeExceeded> ()
1131  ;
1132  return tid;
1133 }
1134 
1136 {
1137  return GetTypeId ();
1138 }
1139 
1141  : m_packet (0)
1142 {
1144 }
1145 
1147 {
1148 }
1149 
1151 {
1152  return m_packet;
1153 }
1154 
1156 {
1157  NS_ASSERT (p->GetSize () <= 1280);
1158  m_packet = p;
1159 }
1160 
1161 void Icmpv6TimeExceeded::Print (std::ostream& os) const
1162 {
1163  os << "( type = " << (uint32_t)GetType () << " (Destination Unreachable) code = " << (uint32_t)GetCode () << " checksum = " << (uint32_t)GetChecksum () << ")";
1164 }
1165 
1167 {
1168  return 8 + m_packet->GetSize ();
1169 }
1170 
1172 {
1173  uint16_t checksum = 0;
1174  Buffer::Iterator i = start;
1175 
1176  i.WriteU8 (GetType ());
1177  i.WriteU8 (GetCode ());
1178  i.WriteHtonU16 (0);
1179  i.WriteHtonU32 (0);
1180 
1181  uint32_t size = m_packet->GetSize ();
1182  uint8_t *buf = new uint8_t[size];
1183  m_packet->CopyData (buf, size);
1184  i.Write (buf, size);
1185  delete[] buf;
1186 
1187  i = start;
1188  checksum = i.CalculateIpChecksum (i.GetSize (), GetChecksum ());
1189 
1190  i = start;
1191  i.Next (2);
1192  i.WriteU16 (checksum);
1193 }
1194 
1196 {
1197  uint16_t length = start.GetSize () - 8;
1198  uint8_t* data = new uint8_t[length];
1199  Buffer::Iterator i = start;
1200 
1201  SetType (i.ReadU8 ());
1202  SetCode (i.ReadU8 ());
1203  m_checksum = i.ReadU16 ();
1204  i.ReadNtohU32 ();
1205  i.Read (data, length);
1206  m_packet = Create<Packet> (data, length);
1207 
1208  delete[] data;
1209  return GetSerializedSize ();
1210 }
1211 
1213 
1215 {
1216  static TypeId tid = TypeId ("ns3::Icmpv6ParameterError")
1217  .SetParent<Icmpv6Header> ()
1218  .AddConstructor<Icmpv6ParameterError> ()
1219  ;
1220  return tid;
1221 }
1222 
1224 {
1225  return GetTypeId ();
1226 }
1227 
1229  : m_packet (0),
1230  m_ptr (0)
1231 {
1233 }
1234 
1236 {
1237 }
1238 
1240 {
1241  return m_packet;
1242 }
1243 
1245 {
1246  NS_ASSERT (p->GetSize () <= 1280);
1247  m_packet = p;
1248 }
1249 
1251 {
1252  return m_ptr;
1253 }
1254 
1255 void Icmpv6ParameterError::SetPtr (uint32_t ptr)
1256 {
1257  m_ptr = ptr;
1258 }
1259 
1260 void Icmpv6ParameterError::Print (std::ostream& os) const
1261 {
1262  os << "( type = " << (uint32_t)GetType () << " (Destination Unreachable) code = " << (uint32_t)GetCode () << " checksum = " << (uint32_t)GetChecksum () << " ptr = " << (uint32_t)GetPtr () << ")";
1263 }
1264 
1266 {
1267  return 8 + m_packet->GetSize ();
1268 }
1269 
1271 {
1272  uint16_t checksum = 0;
1273  Buffer::Iterator i = start;
1274 
1275  i.WriteU8 (GetType ());
1276  i.WriteU8 (GetCode ());
1277  i.WriteHtonU16 (0);
1278  i.WriteHtonU32 (GetPtr ());
1279 
1280  uint32_t size = m_packet->GetSize ();
1281  uint8_t *buf = new uint8_t[size];
1282  m_packet->CopyData (buf, size);
1283  i.Write (buf, size);
1284  delete[] buf;
1285 
1286  i = start;
1287  checksum = i.CalculateIpChecksum (i.GetSize (), GetChecksum ());
1288 
1289  i = start;
1290  i.Next (2);
1291  i.WriteU16 (checksum);
1292 }
1293 
1295 {
1296  uint16_t length = start.GetSize () - 8;
1297  uint8_t* data = new uint8_t[length];
1298  Buffer::Iterator i = start;
1299 
1300  SetType (i.ReadU8 ());
1301  SetCode (i.ReadU8 ());
1302  m_checksum = i.ReadU16 ();
1303  SetPtr (i.ReadNtohU32 ());
1304  i.Read (data, length);
1305  m_packet = Create<Packet> (data, length);
1306  delete[] data;
1307 
1308  return GetSerializedSize ();
1309 }
1310 
1312 
1314 {
1315  static TypeId tid = TypeId ("ns3::Icmpv6OptionHeader")
1316  .SetParent<Header> ()
1317  .AddConstructor<Icmpv6OptionHeader> ()
1318  ;
1319  return tid;
1320 }
1321 
1323 {
1324  return GetTypeId ();
1325 }
1326 
1327 
1329 {
1330  /* TODO */
1331  m_type = 0;
1332  m_len = 0;
1333 }
1334 
1336 {
1337 }
1338 
1340 {
1342  return m_type;
1343 }
1344 
1345 void Icmpv6OptionHeader::SetType (uint8_t type)
1346 {
1348  m_type = type;
1349 }
1350 
1352 {
1354  return m_len;
1355 }
1356 
1358 {
1360  m_len = len;
1361 }
1362 
1363 void Icmpv6OptionHeader::Print (std::ostream& os) const
1364 {
1365  os << "( type = " << (uint32_t)GetType () << " length = " << (uint32_t)GetLength () << ")";
1366 }
1367 
1369 {
1370  return m_len*8;
1371 }
1372 
1374 {
1375  return GetSerializedSize ();
1376 }
1377 
1379 {
1380 }
1381 
1383 
1385 {
1386  static TypeId tid = TypeId ("ns3::Icmpv6OptionMtu")
1388  .AddConstructor<Icmpv6OptionMtu> ()
1389  ;
1390  return tid;
1391 }
1392 
1394 {
1395  return GetTypeId ();
1396 }
1397 
1399 {
1401  SetLength (1);
1402  SetReserved (0);
1403 }
1404 
1406  : m_mtu (mtu)
1407 {
1409  SetLength (1);
1410  SetReserved (0);
1411 }
1412 
1414 {
1415 }
1416 
1418 {
1419  return m_reserved;
1420 }
1421 
1422 void Icmpv6OptionMtu::SetReserved (uint16_t reserved)
1423 {
1424  m_reserved = reserved;
1425 }
1426 
1427 uint32_t Icmpv6OptionMtu::GetMtu () const
1428 {
1429  return m_mtu;
1430 }
1431 
1432 void Icmpv6OptionMtu::SetMtu (uint32_t mtu)
1433 {
1434  m_mtu = mtu;
1435 }
1436 
1437 void Icmpv6OptionMtu::Print (std::ostream& os) const
1438 {
1439  os << "( type = " << (uint32_t)GetType () << " length = " << (uint32_t)GetLength () << " MTU = " << m_mtu << ")";
1440 }
1441 
1443 {
1444  return 8; /* m_len = 1 so the real size is multiple by 8 */
1445 }
1446 
1448 {
1449  Buffer::Iterator i = start;
1450  i.WriteU8 (GetType ());
1451  i.WriteU8 (GetLength ());
1452  i.WriteHtonU16 (GetReserved ());
1453  i.WriteHtonU32 (GetMtu ());
1454 }
1455 
1457 {
1458  Buffer::Iterator i = start;
1459  SetType (i.ReadU8 ());
1460  SetLength (i.ReadU8 ());
1461  SetReserved (i.ReadNtohU16 ());
1462  SetMtu (i.ReadNtohU32 ());
1463  return GetSerializedSize ();
1464 }
1465 
1467 
1469 {
1470  static TypeId tid = TypeId ("ns3::Icmpv6OptionPrefixInformation")
1472  .AddConstructor<Icmpv6OptionPrefixInformation> ()
1473  ;
1474  return tid;
1475 }
1476 
1478 {
1479  return GetTypeId ();
1480 }
1481 
1483 {
1485  SetLength (4);
1486  SetPrefix (Ipv6Address ("::"));
1487  SetPrefixLength (0);
1488  SetValidTime (0);
1489  SetPreferredTime (0);
1490  SetFlags (0);
1491  SetReserved (0);
1492 }
1493 
1495 {
1497  SetLength (4);
1498  SetPrefix (prefix);
1499  SetPrefixLength (prefixlen);
1500  SetValidTime (0);
1501  SetPreferredTime (0);
1502  SetFlags (0);
1503  SetReserved (0);
1504 }
1505 
1507 {
1508 }
1509 
1511 {
1512  return m_prefixLength;
1513 }
1514 
1516 {
1517  NS_ASSERT (prefixLength <= 128);
1518  m_prefixLength = prefixLength;
1519 }
1520 
1522 {
1523  return m_flags;
1524 }
1525 
1527 {
1528  m_flags = flags;
1529 }
1530 
1532 {
1533  return m_validTime;
1534 }
1535 
1537 {
1538  m_validTime = validTime;
1539 }
1540 
1542 {
1543  return m_preferredTime;
1544 }
1545 
1547 {
1548  m_preferredTime = preferredTime;
1549 }
1550 
1552 {
1553  return m_preferredTime;
1554 }
1555 
1557 {
1558  m_reserved = reserved;
1559 }
1560 
1562 {
1563  return m_prefix;
1564 }
1565 
1567 {
1568  m_prefix = prefix;
1569 }
1570 
1571 void Icmpv6OptionPrefixInformation::Print (std::ostream& os) const
1572 {
1573  os << "( type = " << (uint32_t)GetType () << " length = " << (uint32_t)GetLength () << " prefix " << m_prefix << ")";
1574 }
1575 
1577 {
1578  return 32;
1579 }
1580 
1582 {
1583  Buffer::Iterator i = start;
1584  uint8_t buf[16];
1585 
1586  memset (buf, 0x00, sizeof (buf));
1587 
1588  i.WriteU8 (GetType ());
1589  i.WriteU8 (GetLength ());
1590  i.WriteU8 (m_prefixLength);
1591  i.WriteU8 (m_flags);
1595  m_prefix.GetBytes (buf);
1596  i.Write (buf, 16);
1597 }
1598 
1600 {
1601  Buffer::Iterator i = start;
1602  uint8_t buf[16];
1603 
1604  SetType (i.ReadU8 ());
1605  SetLength (i.ReadU8 ());
1606  SetPrefixLength (i.ReadU8 ());
1607  SetFlags (i.ReadU8 ());
1608  SetValidTime (i.ReadNtohU32 ());
1610  SetReserved (i.ReadNtohU32 ());
1611  i.Read (buf, 16);
1612 
1613  Ipv6Address prefix (buf);
1614  SetPrefix (prefix);
1615 
1616  return GetSerializedSize ();
1617 }
1618 
1620 
1622 {
1623  static TypeId tid = TypeId ("ns3::Icmpv6OptionLinkLayerAddress")
1625  .AddConstructor<Icmpv6OptionLinkLayerAddress> ()
1626  ;
1627  return tid;
1628 }
1629 
1631 {
1632  return GetTypeId ();
1633 }
1634 
1636 {
1638 }
1639 
1641 {
1643 }
1644 
1646 {
1648  SetAddress (addr);
1649  SetLength (GetSerializedSize () / 8);
1650 }
1651 
1653 {
1654 }
1655 
1657 {
1658  return m_addr;
1659 }
1660 
1662 {
1663  m_addr = addr;
1664 }
1665 
1666 void Icmpv6OptionLinkLayerAddress::Print (std::ostream& os) const
1667 {
1668  os << "( type = " << (uint32_t)GetType () << " length = " << (uint32_t)GetLength () << " L2 Address = " << m_addr << ")";
1669 }
1670 
1672 {
1673  /* TODO add padding */
1674  uint8_t nb = 2 + m_addr.GetLength ();
1675  return nb;
1676 }
1677 
1679 {
1681  Buffer::Iterator i = start;
1682  uint8_t mac[32];
1683 
1684  i.WriteU8 (GetType ());
1685  i.WriteU8 (GetLength ());
1686  m_addr.CopyTo (mac);
1687  i.Write (mac, m_addr.GetLength ());
1688 
1689  /* XXX if size of the option is not a multiple of 8, add padding */
1690 }
1691 
1693 {
1694  Buffer::Iterator i = start;
1695  uint8_t mac[32];
1696 
1697  SetType (i.ReadU8 ());
1698  SetLength (i.ReadU8 ());
1699  i.Read (mac, (GetLength () * 8) - 2);
1700 
1701  m_addr.CopyFrom (mac, (GetLength () * 8)-2);
1702 
1703  return GetSerializedSize ();
1704 }
1705 
1707 
1709 {
1710  static TypeId tid = TypeId ("ns3::Icmpv6OptionRedirected")
1712  .AddConstructor<Icmpv6OptionRedirected> ()
1713  ;
1714  return tid;
1715 }
1716 
1718 {
1719  return GetTypeId ();
1720 }
1721 
1723  : m_packet (0)
1724 {
1726 }
1727 
1729 {
1730  m_packet = 0;
1731 }
1732 
1734 {
1735  return m_packet;
1736 }
1737 
1739 {
1740  NS_ASSERT (packet->GetSize () <= 1280);
1741  m_packet = packet;
1742  SetLength (1 + (m_packet->GetSize () / 8));
1743 }
1744 
1745 void Icmpv6OptionRedirected::Print (std::ostream& os) const
1746 {
1747  os << "( type = " << (uint32_t)GetType () << " length = " << (uint32_t)GetLength () << ")";
1748 }
1749 
1751 {
1752  return 8 + m_packet->GetSize ();
1753 }
1754 
1756 {
1758  Buffer::Iterator i = start;
1759 
1760  i.WriteU8 (GetType ());
1761  i.WriteU8 (GetLength ());
1762  // Reserved
1763  i.WriteU16 (0);
1764  i.WriteU32 (0);
1765 
1766  uint32_t size = m_packet->GetSize ();
1767  uint8_t *buf = new uint8_t[size];
1768  m_packet->CopyData (buf, size);
1769  i.Write (buf, size);
1770  delete[] buf;
1771 }
1772 
1774 {
1775  Buffer::Iterator i = start;
1776 
1777  SetType (i.ReadU8 ());
1778  uint8_t length = i.ReadU8 ();
1779  SetLength (length);
1780  i.ReadU16 ();
1781  i.ReadU32 ();
1782 
1783  uint32_t len2 = (GetLength () - 1) * 8;
1784  uint8_t* buff = new uint8_t[len2];
1785  i.Read (buff, len2);
1786  m_packet = Create<Packet> (buff, len2);
1787  delete[] buff;
1788 
1789  return GetSerializedSize ();
1790 }
1791 
1792 } /* namespace ns3 */
1793