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 "ns3/assert.h"
22 
23 #include "olsr-header.h"
24 #include "ns3/log.h"
25 
26 #define IPV4_ADDRESS_SIZE 4
27 #define OLSR_MSG_HEADER_SIZE 12
28 #define OLSR_PKT_HEADER_SIZE 4
29 
30 namespace ns3 {
31 namespace olsr {
32 
33 
34 NS_LOG_COMPONENT_DEFINE ("OlsrHeader");
35 
37 #define OLSR_C 0.0625
38 
45 uint8_t
46 SecondsToEmf (double seconds)
47 {
48  int a, b = 0;
49 
50  // find the largest integer 'b' such that: T/C >= 2^b
51  for (b = 0; (seconds/OLSR_C) >= (1 << b); ++b)
52  ;
53  NS_ASSERT ((seconds/OLSR_C) < (1 << b));
54  b--;
55  NS_ASSERT ((seconds/OLSR_C) >= (1 << b));
56 
57  // compute the expression 16*(T/(C*(2^b))-1), which may not be a integer
58  double tmp = 16*(seconds/(OLSR_C*(1<<b))-1);
59 
60  // round it up. This results in the value for 'a'
61  a = (int) ceil (tmp);
62 
63  // if 'a' is equal to 16: increment 'b' by one, and set 'a' to 0
64  if (a == 16)
65  {
66  b += 1;
67  a = 0;
68  }
69 
70  // now, 'a' and 'b' should be integers between 0 and 15,
71  NS_ASSERT (a >= 0 && a < 16);
72  NS_ASSERT (b >= 0 && b < 16);
73 
74  // the field will be a byte holding the value a*16+b
75  return (uint8_t)((a << 4) | b);
76 }
77 
84 double
85 EmfToSeconds (uint8_t olsrFormat)
86 {
87  int a = (olsrFormat >> 4);
88  int b = (olsrFormat & 0xf);
89  // value = C*(1+a/16)*2^b [in seconds]
90  return OLSR_C * (1 + a/16.0) * (1 << b);
91 }
92 
93 
94 
95 // ---------------- OLSR Packet -------------------------------
96 
98 
100 {
101 }
102 
104 {
105 }
106 
107 TypeId
109 {
110  static TypeId tid = TypeId ("ns3::olsr::PacketHeader")
111  .SetParent<Header> ()
112  .AddConstructor<PacketHeader> ()
113  ;
114  return tid;
115 }
116 TypeId
118 {
119  return GetTypeId ();
120 }
121 
122 uint32_t
124 {
125  return OLSR_PKT_HEADER_SIZE;
126 }
127 
128 void
129 PacketHeader::Print (std::ostream &os) const
130 {
131  // TODO
132 }
133 
134 void
136 {
140 }
141 
142 uint32_t
144 {
148  return GetSerializedSize ();
149 }
150 
151 
152 // ---------------- OLSR Message -------------------------------
153 
155 
157  : m_messageType (MessageHeader::MessageType (0))
158 {
159 }
160 
162 {
163 }
164 
165 TypeId
167 {
168  static TypeId tid = TypeId ("ns3::olsr::MessageHeader")
169  .SetParent<Header> ()
170  .AddConstructor<MessageHeader> ()
171  ;
172  return tid;
173 }
174 TypeId
176 {
177  return GetTypeId ();
178 }
179 
180 uint32_t
182 {
183  uint32_t size = OLSR_MSG_HEADER_SIZE;
184  switch (m_messageType)
185  {
186  case MID_MESSAGE:
187  size += m_message.mid.GetSerializedSize ();
188  break;
189  case HELLO_MESSAGE:
190  NS_LOG_DEBUG ("Hello Message Size: " << size << " + " << m_message.hello.GetSerializedSize ());
191  size += m_message.hello.GetSerializedSize ();
192  break;
193  case TC_MESSAGE:
194  size += m_message.tc.GetSerializedSize ();
195  break;
196  case HNA_MESSAGE:
197  size += m_message.hna.GetSerializedSize ();
198  break;
199  default:
200  NS_ASSERT (false);
201  }
202  return size;
203 }
204 
205 void
206 MessageHeader::Print (std::ostream &os) const
207 {
208  // TODO
209 }
210 
211 void
213 {
216  i.WriteU8 (m_vTime);
219  i.WriteU8 (m_timeToLive);
220  i.WriteU8 (m_hopCount);
222 
223  switch (m_messageType)
224  {
225  case MID_MESSAGE:
226  m_message.mid.Serialize (i);
227  break;
228  case HELLO_MESSAGE:
229  m_message.hello.Serialize (i);
230  break;
231  case TC_MESSAGE:
232  m_message.tc.Serialize (i);
233  break;
234  case HNA_MESSAGE:
235  m_message.hna.Serialize (i);
236  break;
237  default:
238  NS_ASSERT (false);
239  }
240 
241 }
242 
243 uint32_t
245 {
246  uint32_t size;
250  m_vTime = i.ReadU8 ();
251  m_messageSize = i.ReadNtohU16 ();
253  m_timeToLive = i.ReadU8 ();
254  m_hopCount = i.ReadU8 ();
256  size = OLSR_MSG_HEADER_SIZE;
257  switch (m_messageType)
258  {
259  case MID_MESSAGE:
260  size += m_message.mid.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
261  break;
262  case HELLO_MESSAGE:
263  size += m_message.hello.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
264  break;
265  case TC_MESSAGE:
266  size += m_message.tc.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
267  break;
268  case HNA_MESSAGE:
269  size += m_message.hna.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
270  break;
271  default:
272  NS_ASSERT (false);
273  }
274  return size;
275 }
276 
277 
278 // ---------------- OLSR MID Message -------------------------------
279 
280 uint32_t
282 {
283  return this->interfaceAddresses.size () * IPV4_ADDRESS_SIZE;
284 }
285 
286 void
287 MessageHeader::Mid::Print (std::ostream &os) const
288 {
289  // TODO
290 }
291 
292 void
294 {
296 
297  for (std::vector<Ipv4Address>::const_iterator iter = this->interfaceAddresses.begin ();
298  iter != this->interfaceAddresses.end (); iter++)
299  {
300  i.WriteHtonU32 (iter->Get ());
301  }
302 }
303 
304 uint32_t
306 {
308 
309  this->interfaceAddresses.clear ();
310  NS_ASSERT (messageSize % IPV4_ADDRESS_SIZE == 0);
311 
312  int numAddresses = messageSize / IPV4_ADDRESS_SIZE;
313  this->interfaceAddresses.erase (this->interfaceAddresses.begin (),
314  this->interfaceAddresses.end ());
315  for (int n = 0; n < numAddresses; ++n)
316  this->interfaceAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
317  return GetSerializedSize ();
318 }
319 
320 
321 
322 // ---------------- OLSR HELLO Message -------------------------------
323 
324 uint32_t
326 {
327  uint32_t size = 4;
328  for (std::vector<LinkMessage>::const_iterator iter = this->linkMessages.begin ();
329  iter != this->linkMessages.end (); iter++)
330  {
331  const LinkMessage &lm = *iter;
332  size += 4;
333  size += IPV4_ADDRESS_SIZE * lm.neighborInterfaceAddresses.size ();
334  }
335  return size;
336 }
337 
338 void
339 MessageHeader::Hello::Print (std::ostream &os) const
340 {
341  // TODO
342 }
343 
344 void
346 {
348 
349  i.WriteU16 (0); // Reserved
350  i.WriteU8 (this->hTime);
351  i.WriteU8 (this->willingness);
352 
353  for (std::vector<LinkMessage>::const_iterator iter = this->linkMessages.begin ();
354  iter != this->linkMessages.end (); iter++)
355  {
356  const LinkMessage &lm = *iter;
357 
358  i.WriteU8 (lm.linkCode);
359  i.WriteU8 (0); // Reserved
360 
361  // The size of the link message, counted in bytes and measured
362  // from the beginning of the "Link Code" field and until the
363  // next "Link Code" field (or - if there are no more link types
364  // - the end of the message).
366 
367  for (std::vector<Ipv4Address>::const_iterator neigh_iter = lm.neighborInterfaceAddresses.begin ();
368  neigh_iter != lm.neighborInterfaceAddresses.end (); neigh_iter++)
369  {
370  i.WriteHtonU32 (neigh_iter->Get ());
371  }
372  }
373 }
374 
375 uint32_t
377 {
379 
380  NS_ASSERT (messageSize >= 4);
381 
382  this->linkMessages.clear ();
383 
384  uint16_t helloSizeLeft = messageSize;
385 
386  i.ReadNtohU16 (); // Reserved
387  this->hTime = i.ReadU8 ();
388  this->willingness = i.ReadU8 ();
389 
390  helloSizeLeft -= 4;
391 
392  while (helloSizeLeft)
393  {
394  LinkMessage lm;
395  NS_ASSERT (helloSizeLeft >= 4);
396  lm.linkCode = i.ReadU8 ();
397  i.ReadU8 (); // Reserved
398  uint16_t lmSize = i.ReadNtohU16 ();
399  NS_ASSERT ((lmSize - 4) % IPV4_ADDRESS_SIZE == 0);
400  for (int n = (lmSize - 4) / IPV4_ADDRESS_SIZE; n; --n)
401  {
402  lm.neighborInterfaceAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
403  }
404  helloSizeLeft -= lmSize;
405  this->linkMessages.push_back (lm);
406  }
407 
408  return messageSize;
409 }
410 
411 
412 
413 // ---------------- OLSR TC Message -------------------------------
414 
415 uint32_t
417 {
418  return 4 + this->neighborAddresses.size () * IPV4_ADDRESS_SIZE;
419 }
420 
421 void
422 MessageHeader::Tc::Print (std::ostream &os) const
423 {
424  // TODO
425 }
426 
427 void
429 {
431 
432  i.WriteHtonU16 (this->ansn);
433  i.WriteHtonU16 (0); // Reserved
434 
435  for (std::vector<Ipv4Address>::const_iterator iter = this->neighborAddresses.begin ();
436  iter != this->neighborAddresses.end (); iter++)
437  {
438  i.WriteHtonU32 (iter->Get ());
439  }
440 }
441 
442 uint32_t
444 {
446 
447  this->neighborAddresses.clear ();
448  NS_ASSERT (messageSize >= 4);
449 
450  this->ansn = i.ReadNtohU16 ();
451  i.ReadNtohU16 (); // Reserved
452 
453  NS_ASSERT ((messageSize - 4) % IPV4_ADDRESS_SIZE == 0);
454  int numAddresses = (messageSize - 4) / IPV4_ADDRESS_SIZE;
455  this->neighborAddresses.clear ();
456  for (int n = 0; n < numAddresses; ++n)
457  this->neighborAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
458 
459  return messageSize;
460 }
461 
462 
463 // ---------------- OLSR HNA Message -------------------------------
464 
465 uint32_t
467 {
468  return 2*this->associations.size () * IPV4_ADDRESS_SIZE;
469 }
470 
471 void
472 MessageHeader::Hna::Print (std::ostream &os) const
473 {
474  // TODO
475 }
476 
477 void
479 {
481 
482  for (size_t n = 0; n < this->associations.size (); ++n)
483  {
484  i.WriteHtonU32 (this->associations[n].address.Get ());
485  i.WriteHtonU32 (this->associations[n].mask.Get ());
486  }
487 }
488 
489 uint32_t
491 {
493 
494  NS_ASSERT (messageSize % (IPV4_ADDRESS_SIZE*2) == 0);
495  int numAddresses = messageSize / IPV4_ADDRESS_SIZE / 2;
496  this->associations.clear ();
497  for (int n = 0; n < numAddresses; ++n)
498  {
499  Ipv4Address address (i.ReadNtohU32 ());
500  Ipv4Mask mask (i.ReadNtohU32 ());
501  this->associations.push_back ((Association) { address, mask});
502  }
503  return messageSize;
504 }
505 
506 }
507 } // namespace olsr, ns3
508