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  NS_ASSERT_MSG (seconds >= OLSR_C, "SecondsToEmf - Can not convert a value less than OLSR_C");
54 
55  // find the largest integer 'b' such that: T/C >= 2^b
56  for (b = 1; (seconds / OLSR_C) >= (1 << b); ++b)
57  {
58  }
59  NS_ASSERT ((seconds / OLSR_C) < (1 << b));
60  b--;
61  NS_ASSERT ((seconds / OLSR_C) >= (1 << b));
62 
63  // compute the expression 16*(T/(C*(2^b))-1), which may not be a integer
64  double tmp = 16 * (seconds / (OLSR_C * (1 << b)) - 1);
65 
66  // round it up. This results in the value for 'a'
67  a = (int) std::ceil (tmp - 0.5);
68 
69  // if 'a' is equal to 16: increment 'b' by one, and set 'a' to 0
70  if (a == 16)
71  {
72  b += 1;
73  a = 0;
74  }
75 
76  // now, 'a' and 'b' should be integers between 0 and 15,
77  NS_ASSERT (a >= 0 && a < 16);
78  NS_ASSERT (b >= 0 && b < 16);
79 
80  // the field will be a byte holding the value a*16+b
81  return (uint8_t)((a << 4) | b);
82 }
83 
90 double
91 EmfToSeconds (uint8_t olsrFormat)
92 {
93  int a = (olsrFormat >> 4);
94  int b = (olsrFormat & 0xf);
95  // value = C*(1+a/16)*2^b [in seconds]
96  return OLSR_C * (1 + a / 16.0) * (1 << b);
97 }
98 
99 
100 
101 // ---------------- OLSR Packet -------------------------------
102 
103 NS_OBJECT_ENSURE_REGISTERED (PacketHeader);
104 
106 {
107 }
108 
110 {
111 }
112 
113 TypeId
115 {
116  static TypeId tid = TypeId ("ns3::olsr::PacketHeader")
117  .SetParent<Header> ()
118  .SetGroupName ("Olsr")
119  .AddConstructor<PacketHeader> ()
120  ;
121  return tid;
122 }
123 TypeId
125 {
126  return GetTypeId ();
127 }
128 
129 uint32_t
131 {
132  return OLSR_PKT_HEADER_SIZE;
133 }
134 
135 void
136 PacketHeader::Print (std::ostream &os) const
137 {
139 }
140 
141 void
143 {
147 }
148 
149 uint32_t
151 {
155  return GetSerializedSize ();
156 }
157 
158 
159 // ---------------- OLSR Message -------------------------------
160 
162 
164  : m_messageType (MessageHeader::MessageType (0))
165 {
166 }
167 
169 {
170 }
171 
172 TypeId
174 {
175  static TypeId tid = TypeId ("ns3::olsr::MessageHeader")
176  .SetParent<Header> ()
177  .SetGroupName ("Olsr")
178  .AddConstructor<MessageHeader> ()
179  ;
180  return tid;
181 }
182 TypeId
184 {
185  return GetTypeId ();
186 }
187 
188 uint32_t
190 {
191  uint32_t size = OLSR_MSG_HEADER_SIZE;
192  switch (m_messageType)
193  {
194  case MID_MESSAGE:
195  size += m_message.mid.GetSerializedSize ();
196  break;
197  case HELLO_MESSAGE:
198  NS_LOG_DEBUG ("Hello Message Size: " << size << " + " << m_message.hello.GetSerializedSize ());
199  size += m_message.hello.GetSerializedSize ();
200  break;
201  case TC_MESSAGE:
202  size += m_message.tc.GetSerializedSize ();
203  break;
204  case HNA_MESSAGE:
205  size += m_message.hna.GetSerializedSize ();
206  break;
207  default:
208  NS_ASSERT (false);
209  }
210  return size;
211 }
212 
213 void
214 MessageHeader::Print (std::ostream &os) const
215 {
217 }
218 
219 void
221 {
224  i.WriteU8 (m_vTime);
227  i.WriteU8 (m_timeToLive);
228  i.WriteU8 (m_hopCount);
230 
231  switch (m_messageType)
232  {
233  case MID_MESSAGE:
234  m_message.mid.Serialize (i);
235  break;
236  case HELLO_MESSAGE:
237  m_message.hello.Serialize (i);
238  break;
239  case TC_MESSAGE:
240  m_message.tc.Serialize (i);
241  break;
242  case HNA_MESSAGE:
243  m_message.hna.Serialize (i);
244  break;
245  default:
246  NS_ASSERT (false);
247  }
248 
249 }
250 
251 uint32_t
253 {
254  uint32_t size;
258  m_vTime = i.ReadU8 ();
259  m_messageSize = i.ReadNtohU16 ();
261  m_timeToLive = i.ReadU8 ();
262  m_hopCount = i.ReadU8 ();
264  size = OLSR_MSG_HEADER_SIZE;
265  switch (m_messageType)
266  {
267  case MID_MESSAGE:
268  size += m_message.mid.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
269  break;
270  case HELLO_MESSAGE:
271  size += m_message.hello.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
272  break;
273  case TC_MESSAGE:
274  size += m_message.tc.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
275  break;
276  case HNA_MESSAGE:
277  size += m_message.hna.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
278  break;
279  default:
280  NS_ASSERT (false);
281  }
282  return size;
283 }
284 
285 
286 // ---------------- OLSR MID Message -------------------------------
287 
288 uint32_t
290 {
291  return this->interfaceAddresses.size () * IPV4_ADDRESS_SIZE;
292 }
293 
294 void
295 MessageHeader::Mid::Print (std::ostream &os) const
296 {
298 }
299 
300 void
302 {
304 
305  for (std::vector<Ipv4Address>::const_iterator iter = this->interfaceAddresses.begin ();
306  iter != this->interfaceAddresses.end (); iter++)
307  {
308  i.WriteHtonU32 (iter->Get ());
309  }
310 }
311 
312 uint32_t
314 {
316 
317  this->interfaceAddresses.clear ();
318  NS_ASSERT (messageSize % IPV4_ADDRESS_SIZE == 0);
319 
320  int numAddresses = messageSize / IPV4_ADDRESS_SIZE;
321  this->interfaceAddresses.erase (this->interfaceAddresses.begin (),
322  this->interfaceAddresses.end ());
323  for (int n = 0; n < numAddresses; ++n)
324  {
325  this->interfaceAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
326  }
327  return GetSerializedSize ();
328 }
329 
330 
331 
332 // ---------------- OLSR HELLO Message -------------------------------
333 
334 uint32_t
336 {
337  uint32_t size = 4;
338  for (std::vector<LinkMessage>::const_iterator iter = this->linkMessages.begin ();
339  iter != this->linkMessages.end (); iter++)
340  {
341  const LinkMessage &lm = *iter;
342  size += 4;
343  size += IPV4_ADDRESS_SIZE * lm.neighborInterfaceAddresses.size ();
344  }
345  return size;
346 }
347 
348 void
349 MessageHeader::Hello::Print (std::ostream &os) const
350 {
352 }
353 
354 void
356 {
358 
359  i.WriteU16 (0); // Reserved
360  i.WriteU8 (this->hTime);
361  i.WriteU8 (this->willingness);
362 
363  for (std::vector<LinkMessage>::const_iterator iter = this->linkMessages.begin ();
364  iter != this->linkMessages.end (); iter++)
365  {
366  const LinkMessage &lm = *iter;
367 
368  i.WriteU8 (lm.linkCode);
369  i.WriteU8 (0); // Reserved
370 
371  // The size of the link message, counted in bytes and measured
372  // from the beginning of the "Link Code" field and until the
373  // next "Link Code" field (or - if there are no more link types
374  // - the end of the message).
376 
377  for (std::vector<Ipv4Address>::const_iterator neigh_iter = lm.neighborInterfaceAddresses.begin ();
378  neigh_iter != lm.neighborInterfaceAddresses.end (); neigh_iter++)
379  {
380  i.WriteHtonU32 (neigh_iter->Get ());
381  }
382  }
383 }
384 
385 uint32_t
387 {
389 
390  NS_ASSERT (messageSize >= 4);
391 
392  this->linkMessages.clear ();
393 
394  uint16_t helloSizeLeft = messageSize;
395 
396  i.ReadNtohU16 (); // Reserved
397  this->hTime = i.ReadU8 ();
398  this->willingness = i.ReadU8 ();
399 
400  helloSizeLeft -= 4;
401 
402  while (helloSizeLeft)
403  {
404  LinkMessage lm;
405  NS_ASSERT (helloSizeLeft >= 4);
406  lm.linkCode = i.ReadU8 ();
407  i.ReadU8 (); // Reserved
408  uint16_t lmSize = i.ReadNtohU16 ();
409  NS_ASSERT ((lmSize - 4) % IPV4_ADDRESS_SIZE == 0);
410  for (int n = (lmSize - 4) / IPV4_ADDRESS_SIZE; n; --n)
411  {
412  lm.neighborInterfaceAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
413  }
414  helloSizeLeft -= lmSize;
415  this->linkMessages.push_back (lm);
416  }
417 
418  return messageSize;
419 }
420 
421 
422 
423 // ---------------- OLSR TC Message -------------------------------
424 
425 uint32_t
427 {
428  return 4 + this->neighborAddresses.size () * IPV4_ADDRESS_SIZE;
429 }
430 
431 void
432 MessageHeader::Tc::Print (std::ostream &os) const
433 {
435 }
436 
437 void
439 {
441 
442  i.WriteHtonU16 (this->ansn);
443  i.WriteHtonU16 (0); // Reserved
444 
445  for (std::vector<Ipv4Address>::const_iterator iter = this->neighborAddresses.begin ();
446  iter != this->neighborAddresses.end (); iter++)
447  {
448  i.WriteHtonU32 (iter->Get ());
449  }
450 }
451 
452 uint32_t
454 {
456 
457  this->neighborAddresses.clear ();
458  NS_ASSERT (messageSize >= 4);
459 
460  this->ansn = i.ReadNtohU16 ();
461  i.ReadNtohU16 (); // Reserved
462 
463  NS_ASSERT ((messageSize - 4) % IPV4_ADDRESS_SIZE == 0);
464  int numAddresses = (messageSize - 4) / IPV4_ADDRESS_SIZE;
465  this->neighborAddresses.clear ();
466  for (int n = 0; n < numAddresses; ++n)
467  {
468  this->neighborAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
469  }
470 
471  return messageSize;
472 }
473 
474 
475 // ---------------- OLSR HNA Message -------------------------------
476 
477 uint32_t
479 {
480  return 2 * this->associations.size () * IPV4_ADDRESS_SIZE;
481 }
482 
483 void
484 MessageHeader::Hna::Print (std::ostream &os) const
485 {
487 }
488 
489 void
491 {
493 
494  for (size_t n = 0; n < this->associations.size (); ++n)
495  {
496  i.WriteHtonU32 (this->associations[n].address.Get ());
497  i.WriteHtonU32 (this->associations[n].mask.Get ());
498  }
499 }
500 
501 uint32_t
503 {
505 
506  NS_ASSERT (messageSize % (IPV4_ADDRESS_SIZE * 2) == 0);
507  int numAddresses = messageSize / IPV4_ADDRESS_SIZE / 2;
508  this->associations.clear ();
509  for (int n = 0; n < numAddresses; ++n)
510  {
512  Ipv4Mask mask (i.ReadNtohU32 ());
513  this->associations.push_back ((Association) { address, mask});
514  }
515  return messageSize;
516 }
517 
518 }
519 } // namespace olsr, ns3
520 
Protocol header serialization and deserialization.
Definition: header.h:42
void Print(std::ostream &os) const
This method is used to print the content of a MID message.
Definition: olsr-header.cc:295
uint16_t m_messageSequenceNumber
The message sequence number.
Definition: olsr-header.h:282
uint16_t m_packetLength
The packet length.
Definition: olsr-header.h:118
#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:45
void Serialize(Buffer::Iterator start) const
This method is used by Packet::AddHeader to store a header into the byte buffer of a packet...
Definition: olsr-header.cc:438
This header can store HELP, TC, MID and HNA messages.
Definition: olsr-header.h:157
void Serialize(Buffer::Iterator start) const
This method is used by Packet::AddHeader to store a header into the byte buffer of a packet...
Definition: olsr-header.cc:355
uint32_t GetSerializedSize(void) const
Returns the expected size of the header.
Definition: olsr-header.cc:426
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:269
struct ns3::olsr::MessageHeader::@69 m_message
Structure holding the message content.
#define IPV4_ADDRESS_SIZE
Definition: olsr-header.cc:28
def start()
Definition: core.py:1855
uint32_t Deserialize(Buffer::Iterator start, uint32_t messageSize)
This method is used by Packet::RemoveHeader to re-create a header from the byte buffer of a packet...
Definition: olsr-header.cc:386
virtual void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:220
#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
uint32_t GetSerializedSize(void) const
Returns the expected size of the header.
Definition: olsr-header.cc:289
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
virtual uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:189
uint8_t m_hopCount
The hop count.
Definition: olsr-header.h:281
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
Definition: olsr-header.cc:124
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: olsr-header.cc:150
void Print(std::ostream &os) const
This method is used to print the content of a MID message.
Definition: olsr-header.cc:484
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
Definition: olsr-header.cc:183
MessageType m_messageType
The message type.
Definition: olsr-header.h:277
uint32_t ReadNtohU32(void)
Definition: buffer.h:970
#define OLSR_C
Scaling factor used in RFC 3626.
Definition: olsr-header.cc:40
iterator in a Buffer instance
Definition: buffer.h:98
uint32_t GetSerializedSize(void) const
Returns the expected size of the header.
Definition: olsr-header.cc:478
std::vector< Ipv4Address > interfaceAddresses
Interface Address container.
Definition: olsr-header.h:315
uint16_t m_packetSequenceNumber
The packet sequence number.
Definition: olsr-header.h:119
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: olsr-header.cc:252
virtual void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:142
uint32_t Deserialize(Buffer::Iterator start, uint32_t messageSize)
This method is used by Packet::RemoveHeader to re-create a header from the byte buffer of a packet...
Definition: olsr-header.cc:313
Association item structure.
Definition: olsr-header.h:519
MessageType
Message type.
Definition: olsr-header.h:163
virtual void Print(std::ostream &os) const
Definition: olsr-header.cc:214
void WriteU16(uint16_t data)
Definition: buffer.cc:870
Ipv4Address m_originatorAddress
The originator address.
Definition: olsr-header.h:279
void WriteHtonU16(uint16_t data)
Definition: buffer.h:905
virtual uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:130
uint8_t m_vTime
The validity time.
Definition: olsr-header.h:278
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static TypeId GetTypeId(void)
Get the type ID.
Definition: olsr-header.cc:173
address
Definition: first.py:44
uint8_t m_timeToLive
The time to live.
Definition: olsr-header.h:280
Definition: olsr.py:1
void WriteHtonU32(uint32_t data)
Definition: buffer.h:924
The basic layout of any packet in OLSR is as follows (omitting IP and UDP headers): ...
Definition: olsr-header.h:75
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
void WriteU8(uint8_t data)
Definition: buffer.h:869
void Serialize(Buffer::Iterator start) const
This method is used by Packet::AddHeader to store a header into the byte buffer of a packet...
Definition: olsr-header.cc:490
uint32_t GetSerializedSize(void) const
Returns the expected size of the header.
Definition: olsr-header.cc:335
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
uint32_t Deserialize(Buffer::Iterator start, uint32_t messageSize)
This method is used by Packet::RemoveHeader to re-create a header from the byte buffer of a packet...
Definition: olsr-header.cc:453
void Print(std::ostream &os) const
This method is used to print the content of a MID message.
Definition: olsr-header.cc:432
uint16_t m_messageSize
The message size.
Definition: olsr-header.h:283
uint8_t ReadU8(void)
Definition: buffer.h:1021
uint8_t SecondsToEmf(double seconds)
Converts a decimal number of seconds to the mantissa/exponent format.
Definition: olsr-header.cc:49
uint32_t Get(void) const
Get the host-order 32-bit IP address.
static TypeId GetTypeId(void)
Get the type ID.
Definition: olsr-header.cc:114
double EmfToSeconds(uint8_t olsrFormat)
Converts a number of seconds in the mantissa/exponent format to a decimal number. ...
Definition: olsr-header.cc:91
virtual void Print(std::ostream &os) const
Definition: olsr-header.cc:136
uint16_t ReadNtohU16(void)
Definition: buffer.h:946
void Print(std::ostream &os) const
This method is used to print the content of a MID message.
Definition: olsr-header.cc:349
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
uint32_t Deserialize(Buffer::Iterator start, uint32_t messageSize)
This method is used by Packet::RemoveHeader to re-create a header from the byte buffer of a packet...
Definition: olsr-header.cc:502
#define OLSR_MSG_HEADER_SIZE
Definition: olsr-header.cc:29
void Serialize(Buffer::Iterator start) const
This method is used by Packet::AddHeader to store a header into the byte buffer of a packet...
Definition: olsr-header.cc:301