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