A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
olsr-header.cc
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 
99 NS_OBJECT_ENSURE_REGISTERED (PacketHeader);
100 
101 PacketHeader::PacketHeader ()
102 {
103 }
104 
105 PacketHeader::~PacketHeader ()
106 {
107 }
108 
109 TypeId
110 PacketHeader::GetTypeId (void)
111 {
112  static TypeId tid = TypeId ("ns3::olsr::PacketHeader")
113  .SetParent<Header> ()
114  .AddConstructor<PacketHeader> ()
115  ;
116  return tid;
117 }
118 TypeId
120 {
121  return GetTypeId ();
122 }
123 
124 uint32_t
126 {
127  return OLSR_PKT_HEADER_SIZE;
128 }
129 
130 void
131 PacketHeader::Print (std::ostream &os) const
132 {
133  // TODO
134 }
135 
136 void
138 {
139  Buffer::Iterator i = start;
140  i.WriteHtonU16 (m_packetLength);
141  i.WriteHtonU16 (m_packetSequenceNumber);
142 }
143 
144 uint32_t
146 {
147  Buffer::Iterator i = start;
148  m_packetLength = i.ReadNtohU16 ();
149  m_packetSequenceNumber = i.ReadNtohU16 ();
150  return GetSerializedSize ();
151 }
152 
153 
154 // ---------------- OLSR Message -------------------------------
155 
156 NS_OBJECT_ENSURE_REGISTERED (MessageHeader);
157 
158 MessageHeader::MessageHeader ()
159  : m_messageType (MessageHeader::MessageType (0))
160 {
161 }
162 
163 MessageHeader::~MessageHeader ()
164 {
165 }
166 
167 TypeId
168 MessageHeader::GetTypeId (void)
169 {
170  static TypeId tid = TypeId ("ns3::olsr::MessageHeader")
171  .SetParent<Header> ()
172  .AddConstructor<MessageHeader> ()
173  ;
174  return tid;
175 }
176 TypeId
178 {
179  return GetTypeId ();
180 }
181 
182 uint32_t
184 {
185  uint32_t size = OLSR_MSG_HEADER_SIZE;
186  switch (m_messageType)
187  {
188  case MID_MESSAGE:
189  size += m_message.mid.GetSerializedSize ();
190  break;
191  case HELLO_MESSAGE:
192  NS_LOG_DEBUG ("Hello Message Size: " << size << " + " << m_message.hello.GetSerializedSize ());
193  size += m_message.hello.GetSerializedSize ();
194  break;
195  case TC_MESSAGE:
196  size += m_message.tc.GetSerializedSize ();
197  break;
198  case HNA_MESSAGE:
199  size += m_message.hna.GetSerializedSize ();
200  break;
201  default:
202  NS_ASSERT (false);
203  }
204  return size;
205 }
206 
207 void
208 MessageHeader::Print (std::ostream &os) const
209 {
210  // TODO
211 }
212 
213 void
215 {
216  Buffer::Iterator i = start;
217  i.WriteU8 (m_messageType);
218  i.WriteU8 (m_vTime);
220  i.WriteHtonU32 (m_originatorAddress.Get ());
221  i.WriteU8 (m_timeToLive);
222  i.WriteU8 (m_hopCount);
223  i.WriteHtonU16 (m_messageSequenceNumber);
224 
225  switch (m_messageType)
226  {
227  case MID_MESSAGE:
228  m_message.mid.Serialize (i);
229  break;
230  case HELLO_MESSAGE:
231  m_message.hello.Serialize (i);
232  break;
233  case TC_MESSAGE:
234  m_message.tc.Serialize (i);
235  break;
236  case HNA_MESSAGE:
237  m_message.hna.Serialize (i);
238  break;
239  default:
240  NS_ASSERT (false);
241  }
242 
243 }
244 
245 uint32_t
247 {
248  uint32_t size;
249  Buffer::Iterator i = start;
250  m_messageType = (MessageType) i.ReadU8 ();
251  NS_ASSERT (m_messageType >= HELLO_MESSAGE && m_messageType <= HNA_MESSAGE);
252  m_vTime = i.ReadU8 ();
253  m_messageSize = i.ReadNtohU16 ();
254  m_originatorAddress = Ipv4Address (i.ReadNtohU32 ());
255  m_timeToLive = i.ReadU8 ();
256  m_hopCount = i.ReadU8 ();
257  m_messageSequenceNumber = i.ReadNtohU16 ();
258  size = OLSR_MSG_HEADER_SIZE;
259  switch (m_messageType)
260  {
261  case MID_MESSAGE:
262  size += m_message.mid.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
263  break;
264  case HELLO_MESSAGE:
265  size += m_message.hello.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
266  break;
267  case TC_MESSAGE:
268  size += m_message.tc.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
269  break;
270  case HNA_MESSAGE:
271  size += m_message.hna.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
272  break;
273  default:
274  NS_ASSERT (false);
275  }
276  return size;
277 }
278 
279 
280 // ---------------- OLSR MID Message -------------------------------
281 
282 uint32_t
283 MessageHeader::Mid::GetSerializedSize (void) const
284 {
285  return this->interfaceAddresses.size () * IPV4_ADDRESS_SIZE;
286 }
287 
288 void
289 MessageHeader::Mid::Print (std::ostream &os) const
290 {
291  // TODO
292 }
293 
294 void
295 MessageHeader::Mid::Serialize (Buffer::Iterator start) const
296 {
297  Buffer::Iterator i = start;
298 
299  for (std::vector<Ipv4Address>::const_iterator iter = this->interfaceAddresses.begin ();
300  iter != this->interfaceAddresses.end (); iter++)
301  {
302  i.WriteHtonU32 (iter->Get ());
303  }
304 }
305 
306 uint32_t
307 MessageHeader::Mid::Deserialize (Buffer::Iterator start, uint32_t messageSize)
308 {
309  Buffer::Iterator i = start;
310 
311  this->interfaceAddresses.clear ();
312  NS_ASSERT (messageSize % IPV4_ADDRESS_SIZE == 0);
313 
314  int numAddresses = messageSize / IPV4_ADDRESS_SIZE;
315  this->interfaceAddresses.erase (this->interfaceAddresses.begin (),
316  this->interfaceAddresses.end ());
317  for (int n = 0; n < numAddresses; ++n)
318  this->interfaceAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
319  return GetSerializedSize ();
320 }
321 
322 
323 
324 // ---------------- OLSR HELLO Message -------------------------------
325 
326 uint32_t
327 MessageHeader::Hello::GetSerializedSize (void) const
328 {
329  uint32_t size = 4;
330  for (std::vector<LinkMessage>::const_iterator iter = this->linkMessages.begin ();
331  iter != this->linkMessages.end (); iter++)
332  {
333  const LinkMessage &lm = *iter;
334  size += 4;
335  size += IPV4_ADDRESS_SIZE * lm.neighborInterfaceAddresses.size ();
336  }
337  return size;
338 }
339 
340 void
341 MessageHeader::Hello::Print (std::ostream &os) const
342 {
343  // TODO
344 }
345 
346 void
347 MessageHeader::Hello::Serialize (Buffer::Iterator start) const
348 {
349  Buffer::Iterator i = start;
350 
351  i.WriteU16 (0); // Reserved
352  i.WriteU8 (this->hTime);
353  i.WriteU8 (this->willingness);
354 
355  for (std::vector<LinkMessage>::const_iterator iter = this->linkMessages.begin ();
356  iter != this->linkMessages.end (); iter++)
357  {
358  const LinkMessage &lm = *iter;
359 
360  i.WriteU8 (lm.linkCode);
361  i.WriteU8 (0); // Reserved
362 
363  // The size of the link message, counted in bytes and measured
364  // from the beginning of the "Link Code" field and until the
365  // next "Link Code" field (or - if there are no more link types
366  // - the end of the message).
367  i.WriteHtonU16 (4 + lm.neighborInterfaceAddresses.size () * IPV4_ADDRESS_SIZE);
368 
369  for (std::vector<Ipv4Address>::const_iterator neigh_iter = lm.neighborInterfaceAddresses.begin ();
370  neigh_iter != lm.neighborInterfaceAddresses.end (); neigh_iter++)
371  {
372  i.WriteHtonU32 (neigh_iter->Get ());
373  }
374  }
375 }
376 
377 uint32_t
378 MessageHeader::Hello::Deserialize (Buffer::Iterator start, uint32_t messageSize)
379 {
380  Buffer::Iterator i = start;
381 
382  NS_ASSERT (messageSize >= 4);
383 
384  this->linkMessages.clear ();
385 
386  uint16_t helloSizeLeft = messageSize;
387 
388  i.ReadNtohU16 (); // Reserved
389  this->hTime = i.ReadU8 ();
390  this->willingness = i.ReadU8 ();
391 
392  helloSizeLeft -= 4;
393 
394  while (helloSizeLeft)
395  {
396  LinkMessage lm;
397  NS_ASSERT (helloSizeLeft >= 4);
398  lm.linkCode = i.ReadU8 ();
399  i.ReadU8 (); // Reserved
400  uint16_t lmSize = i.ReadNtohU16 ();
401  NS_ASSERT ((lmSize - 4) % IPV4_ADDRESS_SIZE == 0);
402  for (int n = (lmSize - 4) / IPV4_ADDRESS_SIZE; n; --n)
403  {
404  lm.neighborInterfaceAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
405  }
406  helloSizeLeft -= lmSize;
407  this->linkMessages.push_back (lm);
408  }
409 
410  return messageSize;
411 }
412 
413 
414 
415 // ---------------- OLSR TC Message -------------------------------
416 
417 uint32_t
418 MessageHeader::Tc::GetSerializedSize (void) const
419 {
420  return 4 + this->neighborAddresses.size () * IPV4_ADDRESS_SIZE;
421 }
422 
423 void
424 MessageHeader::Tc::Print (std::ostream &os) const
425 {
426  // TODO
427 }
428 
429 void
430 MessageHeader::Tc::Serialize (Buffer::Iterator start) const
431 {
432  Buffer::Iterator i = start;
433 
434  i.WriteHtonU16 (this->ansn);
435  i.WriteHtonU16 (0); // Reserved
436 
437  for (std::vector<Ipv4Address>::const_iterator iter = this->neighborAddresses.begin ();
438  iter != this->neighborAddresses.end (); iter++)
439  {
440  i.WriteHtonU32 (iter->Get ());
441  }
442 }
443 
444 uint32_t
445 MessageHeader::Tc::Deserialize (Buffer::Iterator start, uint32_t messageSize)
446 {
447  Buffer::Iterator i = start;
448 
449  this->neighborAddresses.clear ();
450  NS_ASSERT (messageSize >= 4);
451 
452  this->ansn = i.ReadNtohU16 ();
453  i.ReadNtohU16 (); // Reserved
454 
455  NS_ASSERT ((messageSize - 4) % IPV4_ADDRESS_SIZE == 0);
456  int numAddresses = (messageSize - 4) / IPV4_ADDRESS_SIZE;
457  this->neighborAddresses.clear ();
458  for (int n = 0; n < numAddresses; ++n)
459  this->neighborAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
460 
461  return messageSize;
462 }
463 
464 
465 // ---------------- OLSR HNA Message -------------------------------
466 
467 uint32_t
468 MessageHeader::Hna::GetSerializedSize (void) const
469 {
470  return 2*this->associations.size () * IPV4_ADDRESS_SIZE;
471 }
472 
473 void
474 MessageHeader::Hna::Print (std::ostream &os) const
475 {
476  // TODO
477 }
478 
479 void
480 MessageHeader::Hna::Serialize (Buffer::Iterator start) const
481 {
482  Buffer::Iterator i = start;
483 
484  for (size_t n = 0; n < this->associations.size (); ++n)
485  {
486  i.WriteHtonU32 (this->associations[n].address.Get ());
487  i.WriteHtonU32 (this->associations[n].mask.Get ());
488  }
489 }
490 
491 uint32_t
492 MessageHeader::Hna::Deserialize (Buffer::Iterator start, uint32_t messageSize)
493 {
494  Buffer::Iterator i = start;
495 
496  NS_ASSERT (messageSize % (IPV4_ADDRESS_SIZE*2) == 0);
497  int numAddresses = messageSize / IPV4_ADDRESS_SIZE / 2;
498  this->associations.clear ();
499  for (int n = 0; n < numAddresses; ++n)
500  {
501  Ipv4Address address (i.ReadNtohU32 ());
502  Ipv4Mask mask (i.ReadNtohU32 ());
503  this->associations.push_back ((Association) { address, mask});
504  }
505  return messageSize;
506 }
507 
508 }
509 } // namespace olsr, ns3
510 
virtual uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:125
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: olsr-header.cc:145
virtual void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:137
uint32_t ReadNtohU32(void)
Definition: buffer.h:791
iterator in a Buffer instance
Definition: buffer.h:98
virtual void Print(std::ostream &os) const
Definition: olsr-header.cc:131
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: olsr-header.cc:246
uint32_t Get(void) const
virtual TypeId GetInstanceTypeId(void) const
Definition: olsr-header.cc:177
void WriteHtonU16(uint16_t data)
Definition: buffer.h:726
virtual void Print(std::ostream &os) const
Definition: olsr-header.cc:208
void WriteHtonU32(uint32_t data)
Definition: buffer.h:745
virtual TypeId GetInstanceTypeId(void) const
Definition: olsr-header.cc:119
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
void WriteU8(uint8_t data)
Definition: buffer.h:690
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
uint8_t ReadU8(void)
Definition: buffer.h:819
uint16_t ReadNtohU16(void)
Definition: buffer.h:767
virtual uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:183
virtual void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:214