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  .SetGroupName ("Olsr")
116  .AddConstructor<PacketHeader> ()
117  ;
118  return tid;
119 }
120 TypeId
122 {
123  return GetTypeId ();
124 }
125 
126 uint32_t
128 {
129  return OLSR_PKT_HEADER_SIZE;
130 }
131 
132 void
133 PacketHeader::Print (std::ostream &os) const
134 {
136 }
137 
138 void
140 {
144 }
145 
146 uint32_t
148 {
152  return GetSerializedSize ();
153 }
154 
155 
156 // ---------------- OLSR Message -------------------------------
157 
159 
161  : m_messageType (MessageHeader::MessageType (0))
162 {
163 }
164 
166 {
167 }
168 
169 TypeId
171 {
172  static TypeId tid = TypeId ("ns3::olsr::MessageHeader")
173  .SetParent<Header> ()
174  .SetGroupName ("Olsr")
175  .AddConstructor<MessageHeader> ()
176  ;
177  return tid;
178 }
179 TypeId
181 {
182  return GetTypeId ();
183 }
184 
185 uint32_t
187 {
188  uint32_t size = OLSR_MSG_HEADER_SIZE;
189  switch (m_messageType)
190  {
191  case MID_MESSAGE:
192  size += m_message.mid.GetSerializedSize ();
193  break;
194  case HELLO_MESSAGE:
195  NS_LOG_DEBUG ("Hello Message Size: " << size << " + " << m_message.hello.GetSerializedSize ());
196  size += m_message.hello.GetSerializedSize ();
197  break;
198  case TC_MESSAGE:
199  size += m_message.tc.GetSerializedSize ();
200  break;
201  case HNA_MESSAGE:
202  size += m_message.hna.GetSerializedSize ();
203  break;
204  default:
205  NS_ASSERT (false);
206  }
207  return size;
208 }
209 
210 void
211 MessageHeader::Print (std::ostream &os) const
212 {
214 }
215 
216 void
218 {
221  i.WriteU8 (m_vTime);
224  i.WriteU8 (m_timeToLive);
225  i.WriteU8 (m_hopCount);
227 
228  switch (m_messageType)
229  {
230  case MID_MESSAGE:
231  m_message.mid.Serialize (i);
232  break;
233  case HELLO_MESSAGE:
234  m_message.hello.Serialize (i);
235  break;
236  case TC_MESSAGE:
237  m_message.tc.Serialize (i);
238  break;
239  case HNA_MESSAGE:
240  m_message.hna.Serialize (i);
241  break;
242  default:
243  NS_ASSERT (false);
244  }
245 
246 }
247 
248 uint32_t
250 {
251  uint32_t size;
255  m_vTime = i.ReadU8 ();
256  m_messageSize = i.ReadNtohU16 ();
258  m_timeToLive = i.ReadU8 ();
259  m_hopCount = i.ReadU8 ();
261  size = OLSR_MSG_HEADER_SIZE;
262  switch (m_messageType)
263  {
264  case MID_MESSAGE:
265  size += m_message.mid.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
266  break;
267  case HELLO_MESSAGE:
268  size += m_message.hello.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
269  break;
270  case TC_MESSAGE:
271  size += m_message.tc.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
272  break;
273  case HNA_MESSAGE:
274  size += m_message.hna.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
275  break;
276  default:
277  NS_ASSERT (false);
278  }
279  return size;
280 }
281 
282 
283 // ---------------- OLSR MID Message -------------------------------
284 
285 uint32_t
287 {
288  return this->interfaceAddresses.size () * IPV4_ADDRESS_SIZE;
289 }
290 
291 void
292 MessageHeader::Mid::Print (std::ostream &os) const
293 {
295 }
296 
297 void
299 {
301 
302  for (std::vector<Ipv4Address>::const_iterator iter = this->interfaceAddresses.begin ();
303  iter != this->interfaceAddresses.end (); iter++)
304  {
305  i.WriteHtonU32 (iter->Get ());
306  }
307 }
308 
309 uint32_t
311 {
313 
314  this->interfaceAddresses.clear ();
315  NS_ASSERT (messageSize % IPV4_ADDRESS_SIZE == 0);
316 
317  int numAddresses = messageSize / IPV4_ADDRESS_SIZE;
318  this->interfaceAddresses.erase (this->interfaceAddresses.begin (),
319  this->interfaceAddresses.end ());
320  for (int n = 0; n < numAddresses; ++n)
321  this->interfaceAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
322  return GetSerializedSize ();
323 }
324 
325 
326 
327 // ---------------- OLSR HELLO Message -------------------------------
328 
329 uint32_t
331 {
332  uint32_t size = 4;
333  for (std::vector<LinkMessage>::const_iterator iter = this->linkMessages.begin ();
334  iter != this->linkMessages.end (); iter++)
335  {
336  const LinkMessage &lm = *iter;
337  size += 4;
338  size += IPV4_ADDRESS_SIZE * lm.neighborInterfaceAddresses.size ();
339  }
340  return size;
341 }
342 
343 void
344 MessageHeader::Hello::Print (std::ostream &os) const
345 {
347 }
348 
349 void
351 {
353 
354  i.WriteU16 (0); // Reserved
355  i.WriteU8 (this->hTime);
356  i.WriteU8 (this->willingness);
357 
358  for (std::vector<LinkMessage>::const_iterator iter = this->linkMessages.begin ();
359  iter != this->linkMessages.end (); iter++)
360  {
361  const LinkMessage &lm = *iter;
362 
363  i.WriteU8 (lm.linkCode);
364  i.WriteU8 (0); // Reserved
365 
366  // The size of the link message, counted in bytes and measured
367  // from the beginning of the "Link Code" field and until the
368  // next "Link Code" field (or - if there are no more link types
369  // - the end of the message).
371 
372  for (std::vector<Ipv4Address>::const_iterator neigh_iter = lm.neighborInterfaceAddresses.begin ();
373  neigh_iter != lm.neighborInterfaceAddresses.end (); neigh_iter++)
374  {
375  i.WriteHtonU32 (neigh_iter->Get ());
376  }
377  }
378 }
379 
380 uint32_t
382 {
384 
385  NS_ASSERT (messageSize >= 4);
386 
387  this->linkMessages.clear ();
388 
389  uint16_t helloSizeLeft = messageSize;
390 
391  i.ReadNtohU16 (); // Reserved
392  this->hTime = i.ReadU8 ();
393  this->willingness = i.ReadU8 ();
394 
395  helloSizeLeft -= 4;
396 
397  while (helloSizeLeft)
398  {
399  LinkMessage lm;
400  NS_ASSERT (helloSizeLeft >= 4);
401  lm.linkCode = i.ReadU8 ();
402  i.ReadU8 (); // Reserved
403  uint16_t lmSize = i.ReadNtohU16 ();
404  NS_ASSERT ((lmSize - 4) % IPV4_ADDRESS_SIZE == 0);
405  for (int n = (lmSize - 4) / IPV4_ADDRESS_SIZE; n; --n)
406  {
407  lm.neighborInterfaceAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
408  }
409  helloSizeLeft -= lmSize;
410  this->linkMessages.push_back (lm);
411  }
412 
413  return messageSize;
414 }
415 
416 
417 
418 // ---------------- OLSR TC Message -------------------------------
419 
420 uint32_t
422 {
423  return 4 + this->neighborAddresses.size () * IPV4_ADDRESS_SIZE;
424 }
425 
426 void
427 MessageHeader::Tc::Print (std::ostream &os) const
428 {
430 }
431 
432 void
434 {
436 
437  i.WriteHtonU16 (this->ansn);
438  i.WriteHtonU16 (0); // Reserved
439 
440  for (std::vector<Ipv4Address>::const_iterator iter = this->neighborAddresses.begin ();
441  iter != this->neighborAddresses.end (); iter++)
442  {
443  i.WriteHtonU32 (iter->Get ());
444  }
445 }
446 
447 uint32_t
449 {
451 
452  this->neighborAddresses.clear ();
453  NS_ASSERT (messageSize >= 4);
454 
455  this->ansn = i.ReadNtohU16 ();
456  i.ReadNtohU16 (); // Reserved
457 
458  NS_ASSERT ((messageSize - 4) % IPV4_ADDRESS_SIZE == 0);
459  int numAddresses = (messageSize - 4) / IPV4_ADDRESS_SIZE;
460  this->neighborAddresses.clear ();
461  for (int n = 0; n < numAddresses; ++n)
462  this->neighborAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
463 
464  return messageSize;
465 }
466 
467 
468 // ---------------- OLSR HNA Message -------------------------------
469 
470 uint32_t
472 {
473  return 2*this->associations.size () * IPV4_ADDRESS_SIZE;
474 }
475 
476 void
477 MessageHeader::Hna::Print (std::ostream &os) const
478 {
480 }
481 
482 void
484 {
486 
487  for (size_t n = 0; n < this->associations.size (); ++n)
488  {
489  i.WriteHtonU32 (this->associations[n].address.Get ());
490  i.WriteHtonU32 (this->associations[n].mask.Get ());
491  }
492 }
493 
494 uint32_t
496 {
498 
499  NS_ASSERT (messageSize % (IPV4_ADDRESS_SIZE*2) == 0);
500  int numAddresses = messageSize / IPV4_ADDRESS_SIZE / 2;
501  this->associations.clear ();
502  for (int n = 0; n < numAddresses; ++n)
503  {
505  Ipv4Mask mask (i.ReadNtohU32 ());
506  this->associations.push_back ((Association) { address, mask});
507  }
508  return messageSize;
509 }
510 
511 }
512 } // namespace olsr, ns3
513 
Protocol header serialization and deserialization.
Definition: header.h:42
void Print(std::ostream &os) const
Definition: olsr-header.cc:427
uint16_t m_messageSequenceNumber
Definition: olsr-header.h:199
void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:298
#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:127
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:226
uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:286
#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:381
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#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:147
virtual void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:139
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:133
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:249
uint32_t Deserialize(Buffer::Iterator start, uint32_t messageSize)
Definition: olsr-header.cc:310
void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:350
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:180
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:483
void Print(std::ostream &os) const
Definition: olsr-header.cc:477
uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:471
virtual void Print(std::ostream &os) const
Definition: olsr-header.cc:211
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static TypeId GetTypeId(void)
Definition: olsr-header.cc:170
void Print(std::ostream &os) const
Definition: olsr-header.cc:292
uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:330
Definition: olsr.py:1
void WriteHtonU32(uint32_t data)
Definition: buffer.h:931
Introspection did not find any typical Config paths.
Definition: olsr-header.h:69
void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:433
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
Definition: olsr-header.cc:121
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:421
void WriteU8(uint8_t data)
Definition: buffer.h:876
void Print(std::ostream &os) const
Definition: olsr-header.cc:344
#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:448
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:186
a unique identifier for an interface.
Definition: type-id.h:57
TypeId SetParent(TypeId tid)
Definition: type-id.cc:638
uint32_t Deserialize(Buffer::Iterator start, uint32_t messageSize)
Definition: olsr-header.cc:495
#define OLSR_MSG_HEADER_SIZE
Definition: olsr-header.cc:29
virtual void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:217