A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 namespace olsr {
34 
35 
36 NS_LOG_COMPONENT_DEFINE ("OlsrHeader");
37 
39 #define OLSR_C 0.0625
40 
47 uint8_t
48 SecondsToEmf (double seconds)
49 {
50  int a, b = 0;
51 
52  // find the largest integer 'b' such that: T/C >= 2^b
53  for (b = 0; (seconds/OLSR_C) >= (1 << b); ++b)
54  ;
55  NS_ASSERT ((seconds/OLSR_C) < (1 << b));
56  b--;
57  NS_ASSERT ((seconds/OLSR_C) >= (1 << b));
58 
59  // compute the expression 16*(T/(C*(2^b))-1), which may not be a integer
60  double tmp = 16*(seconds/(OLSR_C*(1<<b))-1);
61 
62  // round it up. This results in the value for 'a'
63  a = (int) std::ceil (tmp);
64 
65  // if 'a' is equal to 16: increment 'b' by one, and set 'a' to 0
66  if (a == 16)
67  {
68  b += 1;
69  a = 0;
70  }
71 
72  // now, 'a' and 'b' should be integers between 0 and 15,
73  NS_ASSERT (a >= 0 && a < 16);
74  NS_ASSERT (b >= 0 && b < 16);
75 
76  // the field will be a byte holding the value a*16+b
77  return (uint8_t)((a << 4) | b);
78 }
79 
86 double
87 EmfToSeconds (uint8_t olsrFormat)
88 {
89  int a = (olsrFormat >> 4);
90  int b = (olsrFormat & 0xf);
91  // value = C*(1+a/16)*2^b [in seconds]
92  return OLSR_C * (1 + a/16.0) * (1 << b);
93 }
94 
95 
96 
97 // ---------------- OLSR Packet -------------------------------
98 
100  ;
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  ;
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  .AddConstructor<MessageHeader> ()
175  ;
176  return tid;
177 }
178 TypeId
180 {
181  return GetTypeId ();
182 }
183 
184 uint32_t
186 {
187  uint32_t size = OLSR_MSG_HEADER_SIZE;
188  switch (m_messageType)
189  {
190  case MID_MESSAGE:
191  size += m_message.mid.GetSerializedSize ();
192  break;
193  case HELLO_MESSAGE:
194  NS_LOG_DEBUG ("Hello Message Size: " << size << " + " << m_message.hello.GetSerializedSize ());
195  size += m_message.hello.GetSerializedSize ();
196  break;
197  case TC_MESSAGE:
198  size += m_message.tc.GetSerializedSize ();
199  break;
200  case HNA_MESSAGE:
201  size += m_message.hna.GetSerializedSize ();
202  break;
203  default:
204  NS_ASSERT (false);
205  }
206  return size;
207 }
208 
209 void
210 MessageHeader::Print (std::ostream &os) const
211 {
213 }
214 
215 void
217 {
220  i.WriteU8 (m_vTime);
223  i.WriteU8 (m_timeToLive);
224  i.WriteU8 (m_hopCount);
226 
227  switch (m_messageType)
228  {
229  case MID_MESSAGE:
230  m_message.mid.Serialize (i);
231  break;
232  case HELLO_MESSAGE:
233  m_message.hello.Serialize (i);
234  break;
235  case TC_MESSAGE:
236  m_message.tc.Serialize (i);
237  break;
238  case HNA_MESSAGE:
239  m_message.hna.Serialize (i);
240  break;
241  default:
242  NS_ASSERT (false);
243  }
244 
245 }
246 
247 uint32_t
249 {
250  uint32_t size;
254  m_vTime = i.ReadU8 ();
255  m_messageSize = i.ReadNtohU16 ();
257  m_timeToLive = i.ReadU8 ();
258  m_hopCount = i.ReadU8 ();
260  size = OLSR_MSG_HEADER_SIZE;
261  switch (m_messageType)
262  {
263  case MID_MESSAGE:
264  size += m_message.mid.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
265  break;
266  case HELLO_MESSAGE:
267  size += m_message.hello.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
268  break;
269  case TC_MESSAGE:
270  size += m_message.tc.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
271  break;
272  case HNA_MESSAGE:
273  size += m_message.hna.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
274  break;
275  default:
276  NS_ASSERT (false);
277  }
278  return size;
279 }
280 
281 
282 // ---------------- OLSR MID Message -------------------------------
283 
284 uint32_t
286 {
287  return this->interfaceAddresses.size () * IPV4_ADDRESS_SIZE;
288 }
289 
290 void
291 MessageHeader::Mid::Print (std::ostream &os) const
292 {
294 }
295 
296 void
298 {
300 
301  for (std::vector<Ipv4Address>::const_iterator iter = this->interfaceAddresses.begin ();
302  iter != this->interfaceAddresses.end (); iter++)
303  {
304  i.WriteHtonU32 (iter->Get ());
305  }
306 }
307 
308 uint32_t
310 {
312 
313  this->interfaceAddresses.clear ();
314  NS_ASSERT (messageSize % IPV4_ADDRESS_SIZE == 0);
315 
316  int numAddresses = messageSize / IPV4_ADDRESS_SIZE;
317  this->interfaceAddresses.erase (this->interfaceAddresses.begin (),
318  this->interfaceAddresses.end ());
319  for (int n = 0; n < numAddresses; ++n)
320  this->interfaceAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
321  return GetSerializedSize ();
322 }
323 
324 
325 
326 // ---------------- OLSR HELLO Message -------------------------------
327 
328 uint32_t
330 {
331  uint32_t size = 4;
332  for (std::vector<LinkMessage>::const_iterator iter = this->linkMessages.begin ();
333  iter != this->linkMessages.end (); iter++)
334  {
335  const LinkMessage &lm = *iter;
336  size += 4;
337  size += IPV4_ADDRESS_SIZE * lm.neighborInterfaceAddresses.size ();
338  }
339  return size;
340 }
341 
342 void
343 MessageHeader::Hello::Print (std::ostream &os) const
344 {
346 }
347 
348 void
350 {
352 
353  i.WriteU16 (0); // Reserved
354  i.WriteU8 (this->hTime);
355  i.WriteU8 (this->willingness);
356 
357  for (std::vector<LinkMessage>::const_iterator iter = this->linkMessages.begin ();
358  iter != this->linkMessages.end (); iter++)
359  {
360  const LinkMessage &lm = *iter;
361 
362  i.WriteU8 (lm.linkCode);
363  i.WriteU8 (0); // Reserved
364 
365  // The size of the link message, counted in bytes and measured
366  // from the beginning of the "Link Code" field and until the
367  // next "Link Code" field (or - if there are no more link types
368  // - the end of the message).
370 
371  for (std::vector<Ipv4Address>::const_iterator neigh_iter = lm.neighborInterfaceAddresses.begin ();
372  neigh_iter != lm.neighborInterfaceAddresses.end (); neigh_iter++)
373  {
374  i.WriteHtonU32 (neigh_iter->Get ());
375  }
376  }
377 }
378 
379 uint32_t
381 {
383 
384  NS_ASSERT (messageSize >= 4);
385 
386  this->linkMessages.clear ();
387 
388  uint16_t helloSizeLeft = messageSize;
389 
390  i.ReadNtohU16 (); // Reserved
391  this->hTime = i.ReadU8 ();
392  this->willingness = i.ReadU8 ();
393 
394  helloSizeLeft -= 4;
395 
396  while (helloSizeLeft)
397  {
398  LinkMessage lm;
399  NS_ASSERT (helloSizeLeft >= 4);
400  lm.linkCode = i.ReadU8 ();
401  i.ReadU8 (); // Reserved
402  uint16_t lmSize = i.ReadNtohU16 ();
403  NS_ASSERT ((lmSize - 4) % IPV4_ADDRESS_SIZE == 0);
404  for (int n = (lmSize - 4) / IPV4_ADDRESS_SIZE; n; --n)
405  {
406  lm.neighborInterfaceAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
407  }
408  helloSizeLeft -= lmSize;
409  this->linkMessages.push_back (lm);
410  }
411 
412  return messageSize;
413 }
414 
415 
416 
417 // ---------------- OLSR TC Message -------------------------------
418 
419 uint32_t
421 {
422  return 4 + this->neighborAddresses.size () * IPV4_ADDRESS_SIZE;
423 }
424 
425 void
426 MessageHeader::Tc::Print (std::ostream &os) const
427 {
429 }
430 
431 void
433 {
435 
436  i.WriteHtonU16 (this->ansn);
437  i.WriteHtonU16 (0); // Reserved
438 
439  for (std::vector<Ipv4Address>::const_iterator iter = this->neighborAddresses.begin ();
440  iter != this->neighborAddresses.end (); iter++)
441  {
442  i.WriteHtonU32 (iter->Get ());
443  }
444 }
445 
446 uint32_t
448 {
450 
451  this->neighborAddresses.clear ();
452  NS_ASSERT (messageSize >= 4);
453 
454  this->ansn = i.ReadNtohU16 ();
455  i.ReadNtohU16 (); // Reserved
456 
457  NS_ASSERT ((messageSize - 4) % IPV4_ADDRESS_SIZE == 0);
458  int numAddresses = (messageSize - 4) / IPV4_ADDRESS_SIZE;
459  this->neighborAddresses.clear ();
460  for (int n = 0; n < numAddresses; ++n)
461  this->neighborAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
462 
463  return messageSize;
464 }
465 
466 
467 // ---------------- OLSR HNA Message -------------------------------
468 
469 uint32_t
471 {
472  return 2*this->associations.size () * IPV4_ADDRESS_SIZE;
473 }
474 
475 void
476 MessageHeader::Hna::Print (std::ostream &os) const
477 {
479 }
480 
481 void
483 {
485 
486  for (size_t n = 0; n < this->associations.size (); ++n)
487  {
488  i.WriteHtonU32 (this->associations[n].address.Get ());
489  i.WriteHtonU32 (this->associations[n].mask.Get ());
490  }
491 }
492 
493 uint32_t
495 {
497 
498  NS_ASSERT (messageSize % (IPV4_ADDRESS_SIZE*2) == 0);
499  int numAddresses = messageSize / IPV4_ADDRESS_SIZE / 2;
500  this->associations.clear ();
501  for (int n = 0; n < numAddresses; ++n)
502  {
504  Ipv4Mask mask (i.ReadNtohU32 ());
505  this->associations.push_back ((Association) { address, mask});
506  }
507  return messageSize;
508 }
509 
510 }
511 } // namespace olsr, ns3
512 
Protocol header serialization and deserialization.
Definition: header.h:42
void Print(std::ostream &os) const
Definition: olsr-header.cc:426
uint16_t m_messageSequenceNumber
Definition: olsr-header.h:199
void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:297
#define OLSR_PKT_HEADER_SIZE
Definition: olsr-header.cc:30
Doxygen 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:210
NS_LOG_COMPONENT_DEFINE("OlsrHeader")
uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:285
#define IPV4_ADDRESS_SIZE
Definition: olsr-header.cc:28
uint32_t Deserialize(Buffer::Iterator start, uint32_t messageSize)
Definition: olsr-header.cc:380
#define NS_ASSERT(condition)
Definition: assert.h:64
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
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:791
#define OLSR_C
Scaling factor used in RFC 3626.
Definition: olsr-header.cc:39
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
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: olsr-header.cc:248
uint32_t Deserialize(Buffer::Iterator start, uint32_t messageSize)
Definition: olsr-header.cc:309
void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:349
uint32_t Get(void) const
Get the host-order 32-bit IP address.
virtual TypeId GetInstanceTypeId(void) const
Definition: olsr-header.cc:179
void WriteU16(uint16_t data)
Definition: buffer.cc:895
Ipv4Address m_originatorAddress
Definition: olsr-header.h:196
void WriteHtonU16(uint16_t data)
Definition: buffer.h:726
void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:482
void Print(std::ostream &os) const
Definition: olsr-header.cc:476
uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:470
virtual void Print(std::ostream &os) const
Definition: olsr-header.cc:210
static TypeId GetTypeId(void)
Definition: olsr-header.cc:170
void Print(std::ostream &os) const
Definition: olsr-header.cc:291
uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:329
struct ns3::olsr::MessageHeader::@84 m_message
void WriteHtonU32(uint32_t data)
Definition: buffer.h:745
Doxygen introspection did not find any typical Config paths.
Definition: olsr-header.h:69
void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:432
virtual TypeId GetInstanceTypeId(void) const
Definition: olsr-header.cc:120
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:420
void WriteU8(uint8_t data)
Definition: buffer.h:690
void Print(std::ostream &os) const
Definition: olsr-header.cc:343
#define NS_LOG_DEBUG(msg)
Definition: log.h:289
uint32_t Deserialize(Buffer::Iterator start, uint32_t messageSize)
Definition: olsr-header.cc:447
uint8_t ReadU8(void)
Definition: buffer.h:819
uint8_t SecondsToEmf(double seconds)
Converts a decimal number of seconds to the mantissa/exponent format.
Definition: olsr-header.cc:48
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:87
uint16_t ReadNtohU16(void)
Definition: buffer.h:767
virtual uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:185
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
uint32_t Deserialize(Buffer::Iterator start, uint32_t messageSize)
Definition: olsr-header.cc:494
#define OLSR_MSG_HEADER_SIZE
Definition: olsr-header.cc:29
virtual void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:216