A Discrete-Event Network Simulator
API
olsr-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 INESC Porto
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: Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
19  */
20 
21 #include <cmath>
22 
23 #include "ns3/assert.h"
24 #include "ns3/log.h"
25 
26 #include "olsr-header.h"
27 
28 #define IPV4_ADDRESS_SIZE 4
29 #define OLSR_MSG_HEADER_SIZE 12
30 #define OLSR_PKT_HEADER_SIZE 4
31 
32 namespace ns3 {
33 
34 NS_LOG_COMPONENT_DEFINE ("OlsrHeader");
35 
36 namespace olsr {
37 
38 
40 #define OLSR_C 0.0625
41 
48 uint8_t
49 SecondsToEmf (double seconds)
50 {
51  int a, b = 0;
52 
53  // find the largest integer 'b' such that: T/C >= 2^b
54  for (b = 0; (seconds/OLSR_C) >= (1 << b); ++b)
55  ;
56  NS_ASSERT ((seconds/OLSR_C) < (1 << b));
57  b--;
58  NS_ASSERT ((seconds/OLSR_C) >= (1 << b));
59 
60  // compute the expression 16*(T/(C*(2^b))-1), which may not be a integer
61  double tmp = 16*(seconds/(OLSR_C*(1<<b))-1);
62 
63  // round it up. This results in the value for 'a'
64  a = (int) std::ceil (tmp);
65 
66  // if 'a' is equal to 16: increment 'b' by one, and set 'a' to 0
67  if (a == 16)
68  {
69  b += 1;
70  a = 0;
71  }
72 
73  // now, 'a' and 'b' should be integers between 0 and 15,
74  NS_ASSERT (a >= 0 && a < 16);
75  NS_ASSERT (b >= 0 && b < 16);
76 
77  // the field will be a byte holding the value a*16+b
78  return (uint8_t)((a << 4) | b);
79 }
80 
87 double
88 EmfToSeconds (uint8_t olsrFormat)
89 {
90  int a = (olsrFormat >> 4);
91  int b = (olsrFormat & 0xf);
92  // value = C*(1+a/16)*2^b [in seconds]
93  return OLSR_C * (1 + a/16.0) * (1 << b);
94 }
95 
96 
97 
98 // ---------------- OLSR Packet -------------------------------
99 
100 NS_OBJECT_ENSURE_REGISTERED (PacketHeader);
101 
103 {
104 }
105 
107 {
108 }
109 
110 TypeId
112 {
113  static TypeId tid = TypeId ("ns3::olsr::PacketHeader")
114  .SetParent<Header> ()
115  .AddConstructor<PacketHeader> ()
116  ;
117  return tid;
118 }
119 TypeId
121 {
122  return GetTypeId ();
123 }
124 
125 uint32_t
127 {
128  return OLSR_PKT_HEADER_SIZE;
129 }
130 
131 void
132 PacketHeader::Print (std::ostream &os) const
133 {
135 }
136 
137 void
139 {
143 }
144 
145 uint32_t
147 {
151  return GetSerializedSize ();
152 }
153 
154 
155 // ---------------- OLSR Message -------------------------------
156 
158 
160  : m_messageType (MessageHeader::MessageType (0))
161 {
162 }
163 
165 {
166 }
167 
168 TypeId
170 {
171  static TypeId tid = TypeId ("ns3::olsr::MessageHeader")
172  .SetParent<Header> ()
173  .AddConstructor<MessageHeader> ()
174  ;
175  return tid;
176 }
177 TypeId
179 {
180  return GetTypeId ();
181 }
182 
183 uint32_t
185 {
186  uint32_t size = OLSR_MSG_HEADER_SIZE;
187  switch (m_messageType)
188  {
189  case MID_MESSAGE:
190  size += m_message.mid.GetSerializedSize ();
191  break;
192  case HELLO_MESSAGE:
193  NS_LOG_DEBUG ("Hello Message Size: " << size << " + " << m_message.hello.GetSerializedSize ());
194  size += m_message.hello.GetSerializedSize ();
195  break;
196  case TC_MESSAGE:
197  size += m_message.tc.GetSerializedSize ();
198  break;
199  case HNA_MESSAGE:
200  size += m_message.hna.GetSerializedSize ();
201  break;
202  default:
203  NS_ASSERT (false);
204  }
205  return size;
206 }
207 
208 void
209 MessageHeader::Print (std::ostream &os) const
210 {
212 }
213 
214 void
216 {
219  i.WriteU8 (m_vTime);
222  i.WriteU8 (m_timeToLive);
223  i.WriteU8 (m_hopCount);
225 
226  switch (m_messageType)
227  {
228  case MID_MESSAGE:
229  m_message.mid.Serialize (i);
230  break;
231  case HELLO_MESSAGE:
232  m_message.hello.Serialize (i);
233  break;
234  case TC_MESSAGE:
235  m_message.tc.Serialize (i);
236  break;
237  case HNA_MESSAGE:
238  m_message.hna.Serialize (i);
239  break;
240  default:
241  NS_ASSERT (false);
242  }
243 
244 }
245 
246 uint32_t
248 {
249  uint32_t size;
253  m_vTime = i.ReadU8 ();
254  m_messageSize = i.ReadNtohU16 ();
256  m_timeToLive = i.ReadU8 ();
257  m_hopCount = i.ReadU8 ();
259  size = OLSR_MSG_HEADER_SIZE;
260  switch (m_messageType)
261  {
262  case MID_MESSAGE:
263  size += m_message.mid.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
264  break;
265  case HELLO_MESSAGE:
266  size += m_message.hello.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
267  break;
268  case TC_MESSAGE:
269  size += m_message.tc.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
270  break;
271  case HNA_MESSAGE:
272  size += m_message.hna.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
273  break;
274  default:
275  NS_ASSERT (false);
276  }
277  return size;
278 }
279 
280 
281 // ---------------- OLSR MID Message -------------------------------
282 
283 uint32_t
285 {
286  return this->interfaceAddresses.size () * IPV4_ADDRESS_SIZE;
287 }
288 
289 void
290 MessageHeader::Mid::Print (std::ostream &os) const
291 {
293 }
294 
295 void
297 {
299 
300  for (std::vector<Ipv4Address>::const_iterator iter = this->interfaceAddresses.begin ();
301  iter != this->interfaceAddresses.end (); iter++)
302  {
303  i.WriteHtonU32 (iter->Get ());
304  }
305 }
306 
307 uint32_t
309 {
311 
312  this->interfaceAddresses.clear ();
313  NS_ASSERT (messageSize % IPV4_ADDRESS_SIZE == 0);
314 
315  int numAddresses = messageSize / IPV4_ADDRESS_SIZE;
316  this->interfaceAddresses.erase (this->interfaceAddresses.begin (),
317  this->interfaceAddresses.end ());
318  for (int n = 0; n < numAddresses; ++n)
319  this->interfaceAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
320  return GetSerializedSize ();
321 }
322 
323 
324 
325 // ---------------- OLSR HELLO Message -------------------------------
326 
327 uint32_t
329 {
330  uint32_t size = 4;
331  for (std::vector<LinkMessage>::const_iterator iter = this->linkMessages.begin ();
332  iter != this->linkMessages.end (); iter++)
333  {
334  const LinkMessage &lm = *iter;
335  size += 4;
336  size += IPV4_ADDRESS_SIZE * lm.neighborInterfaceAddresses.size ();
337  }
338  return size;
339 }
340 
341 void
342 MessageHeader::Hello::Print (std::ostream &os) const
343 {
345 }
346 
347 void
349 {
351 
352  i.WriteU16 (0); // Reserved
353  i.WriteU8 (this->hTime);
354  i.WriteU8 (this->willingness);
355 
356  for (std::vector<LinkMessage>::const_iterator iter = this->linkMessages.begin ();
357  iter != this->linkMessages.end (); iter++)
358  {
359  const LinkMessage &lm = *iter;
360 
361  i.WriteU8 (lm.linkCode);
362  i.WriteU8 (0); // Reserved
363 
364  // The size of the link message, counted in bytes and measured
365  // from the beginning of the "Link Code" field and until the
366  // next "Link Code" field (or - if there are no more link types
367  // - the end of the message).
369 
370  for (std::vector<Ipv4Address>::const_iterator neigh_iter = lm.neighborInterfaceAddresses.begin ();
371  neigh_iter != lm.neighborInterfaceAddresses.end (); neigh_iter++)
372  {
373  i.WriteHtonU32 (neigh_iter->Get ());
374  }
375  }
376 }
377 
378 uint32_t
380 {
382 
383  NS_ASSERT (messageSize >= 4);
384 
385  this->linkMessages.clear ();
386 
387  uint16_t helloSizeLeft = messageSize;
388 
389  i.ReadNtohU16 (); // Reserved
390  this->hTime = i.ReadU8 ();
391  this->willingness = i.ReadU8 ();
392 
393  helloSizeLeft -= 4;
394 
395  while (helloSizeLeft)
396  {
397  LinkMessage lm;
398  NS_ASSERT (helloSizeLeft >= 4);
399  lm.linkCode = i.ReadU8 ();
400  i.ReadU8 (); // Reserved
401  uint16_t lmSize = i.ReadNtohU16 ();
402  NS_ASSERT ((lmSize - 4) % IPV4_ADDRESS_SIZE == 0);
403  for (int n = (lmSize - 4) / IPV4_ADDRESS_SIZE; n; --n)
404  {
405  lm.neighborInterfaceAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
406  }
407  helloSizeLeft -= lmSize;
408  this->linkMessages.push_back (lm);
409  }
410 
411  return messageSize;
412 }
413 
414 
415 
416 // ---------------- OLSR TC Message -------------------------------
417 
418 uint32_t
420 {
421  return 4 + this->neighborAddresses.size () * IPV4_ADDRESS_SIZE;
422 }
423 
424 void
425 MessageHeader::Tc::Print (std::ostream &os) const
426 {
428 }
429 
430 void
432 {
434 
435  i.WriteHtonU16 (this->ansn);
436  i.WriteHtonU16 (0); // Reserved
437 
438  for (std::vector<Ipv4Address>::const_iterator iter = this->neighborAddresses.begin ();
439  iter != this->neighborAddresses.end (); iter++)
440  {
441  i.WriteHtonU32 (iter->Get ());
442  }
443 }
444 
445 uint32_t
447 {
449 
450  this->neighborAddresses.clear ();
451  NS_ASSERT (messageSize >= 4);
452 
453  this->ansn = i.ReadNtohU16 ();
454  i.ReadNtohU16 (); // Reserved
455 
456  NS_ASSERT ((messageSize - 4) % IPV4_ADDRESS_SIZE == 0);
457  int numAddresses = (messageSize - 4) / IPV4_ADDRESS_SIZE;
458  this->neighborAddresses.clear ();
459  for (int n = 0; n < numAddresses; ++n)
460  this->neighborAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
461 
462  return messageSize;
463 }
464 
465 
466 // ---------------- OLSR HNA Message -------------------------------
467 
468 uint32_t
470 {
471  return 2*this->associations.size () * IPV4_ADDRESS_SIZE;
472 }
473 
474 void
475 MessageHeader::Hna::Print (std::ostream &os) const
476 {
478 }
479 
480 void
482 {
484 
485  for (size_t n = 0; n < this->associations.size (); ++n)
486  {
487  i.WriteHtonU32 (this->associations[n].address.Get ());
488  i.WriteHtonU32 (this->associations[n].mask.Get ());
489  }
490 }
491 
492 uint32_t
494 {
496 
497  NS_ASSERT (messageSize % (IPV4_ADDRESS_SIZE*2) == 0);
498  int numAddresses = messageSize / IPV4_ADDRESS_SIZE / 2;
499  this->associations.clear ();
500  for (int n = 0; n < numAddresses; ++n)
501  {
503  Ipv4Mask mask (i.ReadNtohU32 ());
504  this->associations.push_back ((Association) { address, mask});
505  }
506  return messageSize;
507 }
508 
509 }
510 } // namespace olsr, ns3
511 
Protocol header serialization and deserialization.
Definition: header.h:42
void Print(std::ostream &os) const
Definition: olsr-header.cc:425
uint16_t m_messageSequenceNumber
Definition: olsr-header.h:199
void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:296
#define OLSR_PKT_HEADER_SIZE
Definition: olsr-header.cc:30
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
Introspection did not find any typical Config paths.
Definition: olsr-header.h:116
virtual uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:126
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:226
uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:284
#define IPV4_ADDRESS_SIZE
Definition: olsr-header.cc:28
def start()
Definition: core.py:1482
uint32_t Deserialize(Buffer::Iterator start, uint32_t messageSize)
Definition: olsr-header.cc:379
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: olsr-header.cc:146
virtual void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:138
uint32_t ReadNtohU32(void)
Definition: buffer.h:977
#define OLSR_C
Scaling factor used in RFC 3626.
Definition: olsr-header.cc:40
iterator in a Buffer instance
Definition: buffer.h:98
virtual void Print(std::ostream &os) const
Definition: olsr-header.cc:132
std::vector< Ipv4Address > interfaceAddresses
Definition: olsr-header.h:225
uint16_t m_packetSequenceNumber
Definition: olsr-header.h:95
struct ns3::olsr::MessageHeader::@86 m_message
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: olsr-header.cc:247
uint32_t Deserialize(Buffer::Iterator start, uint32_t messageSize)
Definition: olsr-header.cc:308
void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:348
uint32_t Get(void) const
Get the host-order 32-bit IP address.
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
Definition: olsr-header.cc:178
void WriteU16(uint16_t data)
Definition: buffer.cc:899
Ipv4Address m_originatorAddress
Definition: olsr-header.h:196
void WriteHtonU16(uint16_t data)
Definition: buffer.h:912
void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:481
void Print(std::ostream &os) const
Definition: olsr-header.cc:475
uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:469
virtual void Print(std::ostream &os) const
Definition: olsr-header.cc:209
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static TypeId GetTypeId(void)
Definition: olsr-header.cc:169
void Print(std::ostream &os) const
Definition: olsr-header.cc:290
uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:328
Definition: olsr.py:1
void WriteHtonU32(uint32_t data)
Definition: buffer.h:931
void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:431
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
Definition: olsr-header.cc:120
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:419
void WriteU8(uint8_t data)
Definition: buffer.h:876
void Print(std::ostream &os) const
Definition: olsr-header.cc:342
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
uint32_t Deserialize(Buffer::Iterator start, uint32_t messageSize)
Definition: olsr-header.cc:446
uint8_t ReadU8(void)
Definition: buffer.h:1028
uint8_t SecondsToEmf(double seconds)
Converts a decimal number of seconds to the mantissa/exponent format.
Definition: olsr-header.cc:49
tuple address
Definition: first.py:37
static TypeId GetTypeId(void)
Definition: olsr-header.cc:111
double EmfToSeconds(uint8_t olsrFormat)
Converts a number of seconds in the mantissa/exponent format to a decimal number. ...
Definition: olsr-header.cc:88
uint16_t ReadNtohU16(void)
Definition: buffer.h:953
virtual uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:184
a unique identifier for an interface.
Definition: type-id.h:51
TypeId SetParent(TypeId tid)
Definition: type-id.cc:631
uint32_t Deserialize(Buffer::Iterator start, uint32_t messageSize)
Definition: olsr-header.cc:493
#define OLSR_MSG_HEADER_SIZE
Definition: olsr-header.cc:29
virtual void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:215