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 ((GetLength () >> 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 ((GetLength () >> 3) - 1);
298 
300 }
301 
303 {
305 
306  SetNextHeader (i.ReadU8 ());
307  SetLength ((i.ReadU8 () + 1) << 3);
309 
310  return GetSerializedSize ();
311 }
312 
314 
316 {
317  static TypeId tid = TypeId ("ns3::Ipv6ExtensionFragmentHeader")
319  .SetParent<Ipv6ExtensionHeader> ()
320  ;
321  return tid;
322 }
323 
325 {
326  return GetTypeId ();
327 }
328 
330  : m_offset (0),
331  m_identification (0)
332 {
333 }
334 
336 {
337 }
338 
340 {
341  // Clear the offset, and save the MF bit
342  m_offset &= 1;
343  m_offset |= offset & (~7);
344 }
345 
347 {
348  return m_offset & (~1);
349 }
350 
352 {
353  m_offset = moreFragment ? m_offset | 1 : m_offset & (~1);
354 }
355 
357 {
358  return m_offset & 1;
359 }
360 
362 {
363  m_identification = identification;
364 }
365 
367 {
368  return m_identification;
369 }
370 
371 void Ipv6ExtensionFragmentHeader::Print (std::ostream &os) const
372 {
373  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength ()
374  << " offset = " << (uint32_t)GetOffset () << " MF = " << (uint32_t)GetMoreFragment () << " identification = " << (uint32_t)m_identification << " )";
375 }
376 
378 {
379  return 8;
380 }
381 
383 {
385 
386  i.WriteU8 (GetNextHeader ());
387  i.WriteU8 ((GetLength () >> 3) - 1);
390 }
391 
393 {
395 
396  SetNextHeader (i.ReadU8 ());
397  SetLength ((i.ReadU8 () + 1) << 3);
398  m_offset = i.ReadNtohU16 ();
400 
401  return GetSerializedSize ();
402 }
403 
405 
407 {
408  static TypeId tid = TypeId ("ns3::Ipv6ExtensionRoutingHeader")
410  .SetParent<Ipv6ExtensionHeader> ()
411  ;
412  return tid;
413 }
414 
416 {
417  return GetTypeId ();
418 }
419 
421  : m_typeRouting (0),
422  m_segmentsLeft (0)
423 {
424 }
425 
427 {
428 }
429 
431 {
432  m_typeRouting = typeRouting;
433 }
434 
436 {
437  return m_typeRouting;
438 }
439 
441 {
442  m_segmentsLeft = segmentsLeft;
443 }
444 
446 {
447  return m_segmentsLeft;
448 }
449 
450 void Ipv6ExtensionRoutingHeader::Print (std::ostream &os) const
451 {
452  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength ()
453  << " typeRouting = " << (uint32_t)m_typeRouting << " segmentsLeft = " << (uint32_t)m_segmentsLeft << " )";
454 }
455 
457 {
458  return 4;
459 }
460 
462 {
464 
465  i.WriteU8 (GetNextHeader ());
466  i.WriteU8 ((GetLength () >> 3) - 1);
469 }
470 
472 {
474 
475  SetNextHeader (i.ReadU8 ());
476  SetLength ((i.ReadU8 () + 1) << 3);
477  m_typeRouting = i.ReadU8 ();
478  m_segmentsLeft = i.ReadU8 ();
479 
480  return GetSerializedSize ();
481 }
482 
484 
486 {
487  static TypeId tid = TypeId ("ns3::Ipv6ExtensionLooseRoutingHeader")
489  .SetParent<Ipv6ExtensionRoutingHeader> ()
490  ;
491  return tid;
492 }
493 
495 {
496  return GetTypeId ();
497 }
498 
500  : m_routersAddress (0)
501 {
502 }
503 
505 {
506 }
507 
509 {
510  m_routersAddress.clear ();
511  m_routersAddress.assign (n, Ipv6Address (""));
512 }
513 
514 void Ipv6ExtensionLooseRoutingHeader::SetRoutersAddress (std::vector<Ipv6Address> routersAddress)
515 {
516  m_routersAddress = routersAddress;
517 }
518 
519 std::vector<Ipv6Address> Ipv6ExtensionLooseRoutingHeader::GetRoutersAddress () const
520 {
521  return m_routersAddress;
522 }
523 
525 {
526  m_routersAddress.at (index) = addr;
527 }
528 
530 {
531  return m_routersAddress.at (index);
532 }
533 
534 void Ipv6ExtensionLooseRoutingHeader::Print (std::ostream &os) const
535 {
536  os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength ()
537  << " typeRouting = " << (uint32_t)GetTypeRouting () << " segmentsLeft = " << (uint32_t)GetSegmentsLeft () << " ";
538 
539  for (std::vector<Ipv6Address>::const_iterator it = m_routersAddress.begin (); it != m_routersAddress.end (); it++)
540  {
541  os << *it << " ";
542  }
543 
544  os << " )";
545 }
546 
548 {
549  return 8 + m_routersAddress.size () * 16;
550 }
551 
553 {
555  uint8_t buff[16];
556 
557  i.WriteU8 (GetNextHeader ());
558  i.WriteU8 ((GetLength () >> 3) - 1);
559  i.WriteU8 (GetTypeRouting ());
560  i.WriteU8 (GetSegmentsLeft ());
561  i.WriteU32 (0);
562 
563  for (VectorIpv6Address_t::const_iterator it = m_routersAddress.begin (); it != m_routersAddress.end (); it++)
564  {
565  it->Serialize (buff);
566  i.Write (buff, 16);
567  }
568 }
569 
571 {
573  uint8_t buff[16];
574 
575  SetNextHeader (i.ReadU8 ());
576  SetLength ((i.ReadU8 () + 1) << 3);
577  SetTypeRouting (i.ReadU8 ());
578  SetSegmentsLeft (i.ReadU8 ());
579  i.ReadU32 ();
580 
581  for (std::vector<Ipv6Address>::iterator it = m_routersAddress.begin (); it != m_routersAddress.end (); it++)
582  {
583  i.Read (buff, 16);
584  it->Set (buff);
585  }
586 
587  return GetSerializedSize ();
588 }
589 
591 
593 {
594  static TypeId tid = TypeId ("ns3::Ipv6ExtensionESPHeader")
596  .SetParent<Ipv6ExtensionHeader> ()
597  ;
598  return tid;
599 }
600 
602 {
603  return GetTypeId ();
604 }
605 
607 {
608 }
609 
611 {
612 }
613 
614 void Ipv6ExtensionESPHeader::Print (std::ostream &os) const
615 {
616  /* TODO */
617 }
618 
620 {
621  /* TODO */
622  return 0;
623 }
624 
626 {
627  /* TODO */
628 }
629 
631 {
632  /* TODO */
633  return 0;
634 }
635 
637 
639 {
640  static TypeId tid = TypeId ("ns3::Ipv6ExtensionAHHeader")
642  .SetParent<Ipv6ExtensionHeader> ()
643  ;
644  return tid;
645 }
646 
648 {
649  return GetTypeId ();
650 }
651 
653 {
654 }
655 
657 {
658 }
659 
660 void Ipv6ExtensionAHHeader::Print (std::ostream &os) const
661 {
662  /* TODO */
663 }
664 
666 {
667  /* TODO */
668  return 0;
669 }
670 
672 {
673  /* TODO */
674 }
675 
677 {
678  /* TODO */
679  return 0;
680 }
681 
682 } /* namespace ns3 */
683