A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ipv6-extension-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: David Gross <gdavid.devel@gmail.com>
19  */
20 
21 #include "ns3/assert.h"
22 #include "ns3/log.h"
23 #include "ns3/header.h"
24 #include "ipv6-extension-header.h"
25 
26 namespace ns3
27 {
28 
29 NS_LOG_COMPONENT_DEFINE ("Ipv6ExtensionHeader");
30 
31 NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionHeader);
32 
34 {
35  static TypeId tid = TypeId ("ns3::Ipv6ExtensionHeader")
37  .SetParent<Header> ()
38  ;
39  return tid;
40 }
41 
43 {
44  return GetTypeId ();
45 }
46 
48  : m_nextHeader (0),
49  m_length (0),
50  m_data (0)
51 {
52 }
53 
55 {
56 }
57 
58 void Ipv6ExtensionHeader::SetNextHeader (uint8_t nextHeader)
59 {
60  m_nextHeader = nextHeader;
61 }
62 
64 {
65  return m_nextHeader;
66 }
67 
68 void Ipv6ExtensionHeader::SetLength (uint16_t length)
69 {
70  m_length = (length >> 3) - 1;
71 }
72 
74 {
75  return (m_length + 1) << 3;
76 }
77 
78 void Ipv6ExtensionHeader::Print (std::ostream &os) const
79 {
80  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength () << " )";
81 }
82 
84 {
85  return 2;
86 }
87 
89 {
91 
93  i.WriteU8 (m_length);
94  i.Write (m_data.PeekData (), m_data.GetSize ());
95 }
96 
98 {
100 
101  m_nextHeader = i.ReadU8 ();
102  m_length = i.ReadU8 ();
103 
104  uint32_t dataLength = GetLength () - 2;
105  uint8_t* data = new uint8_t[dataLength];
106  i.Read (data, dataLength);
107 
108  if (dataLength > m_data.GetSize ())
109  {
110  m_data.AddAtEnd (dataLength - m_data.GetSize ());
111  }
112  else
113  {
114  m_data.RemoveAtEnd (m_data.GetSize () - dataLength);
115  }
116 
117  i = m_data.Begin ();
118  i.Write (data, dataLength);
119 
120  delete[] data;
121  return GetSerializedSize ();
122 }
123 
124 OptionField::OptionField (uint32_t optionsOffset)
125  : m_optionData (0),
126  m_optionsOffset (optionsOffset)
127 {
128 }
129 
131 {
132 }
133 
135 {
137 }
138 
140 {
141  start.Write (m_optionData.Begin (), m_optionData.End ());
142  uint32_t fill = CalculatePad ((Ipv6OptionHeader::Alignment) { 8,0});
143  NS_LOG_LOGIC ("fill with " << fill << " bytes padding");
144  switch (fill)
145  {
146  case 0: return;
147  case 1: Ipv6OptionPad1Header ().Serialize (start);
148  return;
149  default: Ipv6OptionPadnHeader (fill).Serialize (start);
150  return;
151  }
152 }
153 
155 {
156  uint8_t* buf = new uint8_t[length];
157  start.Read (buf, length);
158  m_optionData = Buffer ();
159  m_optionData.AddAtEnd (length);
160  m_optionData.Begin ().Write (buf, length);
161  delete[] buf;
162  return length;
163 }
164 
166 {
168 
169  uint32_t pad = CalculatePad (option.GetAlignment ());
170  NS_LOG_LOGIC ("need " << pad << " bytes padding");
171  switch (pad)
172  {
173  case 0: break; //no padding needed
174  case 1: AddOption (Ipv6OptionPad1Header ());
175  break;
176  default: AddOption (Ipv6OptionPadnHeader (pad));
177  break;
178  }
179 
182  it.Prev (option.GetSerializedSize ());
183  option.Serialize (it);
184 }
185 
187 {
188  return (alignment.offset - (m_optionData.GetSize () + m_optionsOffset)) % alignment.factor;
189 }
190 
192 {
193  return m_optionsOffset;
194 }
195 
197 {
198  return m_optionData;
199 }
200 
201 
203 
205 {
206  static TypeId tid = TypeId ("ns3::Ipv6ExtensionHopByHopHeader")
208  .SetParent<Ipv6ExtensionHeader> ()
209  ;
210  return tid;
211 }
212 
214 {
215  return GetTypeId ();
216 }
217 
219  : OptionField (2)
220 {
221 }
222 
224 {
225 }
226 
227 void Ipv6ExtensionHopByHopHeader::Print (std::ostream &os) const
228 {
229  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength () << " )";
230 }
231 
233 {
234  return 2 + OptionField::GetSerializedSize ();
235 }
236 
238 {
240 
241  i.WriteU8 (GetNextHeader ());
242  i.WriteU8 ((GetSerializedSize () >> 3) - 1);
244 }
245 
247 {
249 
250  SetNextHeader (i.ReadU8 ());
251  SetLength ((i.ReadU8 () + 1) << 3);
253 
254  return GetSerializedSize ();
255 }
256 
258 
260 {
261  static TypeId tid = TypeId ("ns3::Ipv6ExtensionDestinationHeader")
263  .SetParent<Ipv6ExtensionHeader> ()
264  ;
265  return tid;
266 }
267 
269 {
270  return GetTypeId ();
271 }
272 
274  : OptionField (2)
275 {
276 }
277 
279 {
280 }
281 
282 void Ipv6ExtensionDestinationHeader::Print (std::ostream &os) const
283 {
284  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength () << " )";
285 }
286 
288 {
289  return 2 + OptionField::GetSerializedSize ();
290 }
291 
293 {
295 
296  i.WriteU8 (GetNextHeader ());
297  i.WriteU8 ((GetSerializedSize () >> 3) - 1);
299 }
300 
302 {
304 
305  SetNextHeader (i.ReadU8 ());
306  SetLength ((i.ReadU8 () + 1) << 3);
308 
309  return GetSerializedSize ();
310 }
311 
313 
315 {
316  static TypeId tid = TypeId ("ns3::Ipv6ExtensionFragmentHeader")
318  .SetParent<Ipv6ExtensionHeader> ()
319  ;
320  return tid;
321 }
322 
324 {
325  return GetTypeId ();
326 }
327 
329  : m_offset (0),
330  m_identification (0)
331 {
332 }
333 
335 {
336 }
337 
339 {
340  // Clear the offset, and save the MF bit
341  m_offset &= 1;
342  m_offset |= offset & (~7);
343 }
344 
346 {
347  return m_offset & (~1);
348 }
349 
351 {
352  m_offset = moreFragment ? m_offset | 1 : m_offset & (~1);
353 }
354 
356 {
357  return m_offset & 1;
358 }
359 
361 {
362  m_identification = identification;
363 }
364 
366 {
367  return m_identification;
368 }
369 
370 void Ipv6ExtensionFragmentHeader::Print (std::ostream &os) const
371 {
372  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength ()
373  << " offset = " << (uint32_t)GetOffset () << " MF = " << (uint32_t)GetMoreFragment () << " identification = " << (uint32_t)m_identification << " )";
374 }
375 
377 {
378  return 8;
379 }
380 
382 {
384 
385  i.WriteU8 (GetNextHeader ());
386  i.WriteU8 ((GetLength () >> 3) - 1);
389 }
390 
392 {
394 
395  SetNextHeader (i.ReadU8 ());
396  SetLength ((i.ReadU8 () + 1) << 3);
397  m_offset = i.ReadNtohU16 ();
399 
400  return GetSerializedSize ();
401 }
402 
404 
406 {
407  static TypeId tid = TypeId ("ns3::Ipv6ExtensionRoutingHeader")
409  .SetParent<Ipv6ExtensionHeader> ()
410  ;
411  return tid;
412 }
413 
415 {
416  return GetTypeId ();
417 }
418 
420  : m_typeRouting (0),
421  m_segmentsLeft (0)
422 {
423 }
424 
426 {
427 }
428 
430 {
431  m_typeRouting = typeRouting;
432 }
433 
435 {
436  return m_typeRouting;
437 }
438 
440 {
441  m_segmentsLeft = segmentsLeft;
442 }
443 
445 {
446  return m_segmentsLeft;
447 }
448 
449 void Ipv6ExtensionRoutingHeader::Print (std::ostream &os) const
450 {
451  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength ()
452  << " typeRouting = " << (uint32_t)m_typeRouting << " segmentsLeft = " << (uint32_t)m_segmentsLeft << " )";
453 }
454 
456 {
457  return 4;
458 }
459 
461 {
463 
464  i.WriteU8 (GetNextHeader ());
465  i.WriteU8 ((GetLength () >> 3) - 1);
468 }
469 
471 {
473 
474  SetNextHeader (i.ReadU8 ());
475  SetLength ((i.ReadU8 () + 1) << 3);
476  m_typeRouting = i.ReadU8 ();
477  m_segmentsLeft = i.ReadU8 ();
478 
479  return GetSerializedSize ();
480 }
481 
483 
485 {
486  static TypeId tid = TypeId ("ns3::Ipv6ExtensionLooseRoutingHeader")
488  .SetParent<Ipv6ExtensionRoutingHeader> ()
489  ;
490  return tid;
491 }
492 
494 {
495  return GetTypeId ();
496 }
497 
499  : m_routersAddress (0)
500 {
501 }
502 
504 {
505 }
506 
508 {
509  m_routersAddress.clear ();
510  m_routersAddress.assign (n, Ipv6Address (""));
511 }
512 
513 void Ipv6ExtensionLooseRoutingHeader::SetRoutersAddress (std::vector<Ipv6Address> routersAddress)
514 {
515  m_routersAddress = routersAddress;
516 }
517 
518 std::vector<Ipv6Address> Ipv6ExtensionLooseRoutingHeader::GetRoutersAddress () const
519 {
520  return m_routersAddress;
521 }
522 
524 {
525  m_routersAddress.at (index) = addr;
526 }
527 
529 {
530  return m_routersAddress.at (index);
531 }
532 
533 void Ipv6ExtensionLooseRoutingHeader::Print (std::ostream &os) const
534 {
535  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength ()
536  << " typeRouting = " << (uint32_t)GetTypeRouting () << " segmentsLeft = " << (uint32_t)GetSegmentsLeft () << " ";
537 
538  for (std::vector<Ipv6Address>::const_iterator it = m_routersAddress.begin (); it != m_routersAddress.end (); it++)
539  {
540  os << *it << " ";
541  }
542 
543  os << " )";
544 }
545 
547 {
548  return 8 + m_routersAddress.size () * 16;
549 }
550 
552 {
554  uint8_t buff[16];
555 
556  i.WriteU8 (GetNextHeader ());
557  i.WriteU8 ((GetLength () >> 3) - 1);
558  i.WriteU8 (GetTypeRouting ());
559  i.WriteU8 (GetSegmentsLeft ());
560  i.WriteU32 (0);
561 
562  for (VectorIpv6Address_t::const_iterator it = m_routersAddress.begin (); it != m_routersAddress.end (); it++)
563  {
564  it->Serialize (buff);
565  i.Write (buff, 16);
566  }
567 }
568 
570 {
572  uint8_t buff[16];
573 
574  SetNextHeader (i.ReadU8 ());
575  SetLength ((i.ReadU8 () + 1) << 3);
576  SetTypeRouting (i.ReadU8 ());
577  SetSegmentsLeft (i.ReadU8 ());
578  i.ReadU32 ();
579 
580  for (std::vector<Ipv6Address>::iterator it = m_routersAddress.begin (); it != m_routersAddress.end (); it++)
581  {
582  i.Read (buff, 16);
583  it->Set (buff);
584  }
585 
586  return GetSerializedSize ();
587 }
588 
590 
592 {
593  static TypeId tid = TypeId ("ns3::Ipv6ExtensionESPHeader")
595  .SetParent<Ipv6ExtensionHeader> ()
596  ;
597  return tid;
598 }
599 
601 {
602  return GetTypeId ();
603 }
604 
606 {
607 }
608 
610 {
611 }
612 
613 void Ipv6ExtensionESPHeader::Print (std::ostream &os) const
614 {
616 }
617 
619 {
621  return 0;
622 }
623 
625 {
627 }
628 
630 {
632  return 0;
633 }
634 
636 
638 {
639  static TypeId tid = TypeId ("ns3::Ipv6ExtensionAHHeader")
641  .SetParent<Ipv6ExtensionHeader> ()
642  ;
643  return tid;
644 }
645 
647 {
648  return GetTypeId ();
649 }
650 
652 {
653 }
654 
656 {
657 }
658 
659 void Ipv6ExtensionAHHeader::Print (std::ostream &os) const
660 {
662 }
663 
665 {
667  return 0;
668 }
669 
671 {
673 }
674 
676 {
678  return 0;
679 }
680 
681 } /* namespace ns3 */
682