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
32namespace ns3 {
33
34NS_LOG_COMPONENT_DEFINE ("OlsrHeader");
35
36namespace olsr {
37
38
40#define OLSR_C 0.0625
41
48uint8_t
49SecondsToEmf (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
90double
91EmfToSeconds (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
103NS_OBJECT_ENSURE_REGISTERED (PacketHeader);
104
106{
107}
108
110{
111}
112
113TypeId
115{
116 static TypeId tid = TypeId ("ns3::olsr::PacketHeader")
117 .SetParent<Header> ()
118 .SetGroupName ("Olsr")
119 .AddConstructor<PacketHeader> ()
120 ;
121 return tid;
122}
123TypeId
125{
126 return GetTypeId ();
127}
128
131{
133}
134
135void
136PacketHeader::Print (std::ostream &os) const
137{
138 os << "len: " << m_packetLength << " seqNo: " << m_packetSequenceNumber;
139}
140
141void
143{
147}
148
151{
155 return GetSerializedSize ();
156}
157
158
159// ---------------- OLSR Message -------------------------------
160
162
164 : m_messageType (MessageHeader::MessageType (0))
165{
166}
167
169{
170}
171
172TypeId
174{
175 static TypeId tid = TypeId ("ns3::olsr::MessageHeader")
176 .SetParent<Header> ()
177 .SetGroupName ("Olsr")
178 .AddConstructor<MessageHeader> ()
179 ;
180 return tid;
181}
182TypeId
184{
185 return GetTypeId ();
186}
187
190{
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
213void
214MessageHeader::Print (std::ostream &os) const
215{
216 switch (m_messageType)
217 {
218 case HELLO_MESSAGE:
219 os << "type: HELLO";
220 break;
221 case TC_MESSAGE:
222 os << "type: TC";
223 break;
224 case MID_MESSAGE:
225 os << "type: MID";
226 break;
227 case HNA_MESSAGE:
228 os << "type: HNA";
229 break;
230 }
231
232 os << " TTL: " << +m_timeToLive;
233 os << " Orig: " << m_originatorAddress;
234 os << " SeqNo: " << m_messageSequenceNumber;
235 os << " Validity: " << +m_vTime;
236 os << " Hop count: " << +m_hopCount;
237 os << " Size: " << m_messageSize;
238
239 switch (m_messageType)
240 {
241 case MID_MESSAGE:
242 m_message.mid.Print (os);
243 break;
244 case HELLO_MESSAGE:
245 m_message.hello.Print (os);
246 break;
247 case TC_MESSAGE:
248 m_message.tc.Print (os);
249 break;
250 case HNA_MESSAGE:
251 m_message.hna.Print (os);
252 break;
253 default:
254 NS_ASSERT (false);
255 }
256}
257
258void
260{
263 i.WriteU8 (m_vTime);
269
270 switch (m_messageType)
271 {
272 case MID_MESSAGE:
273 m_message.mid.Serialize (i);
274 break;
275 case HELLO_MESSAGE:
276 m_message.hello.Serialize (i);
277 break;
278 case TC_MESSAGE:
279 m_message.tc.Serialize (i);
280 break;
281 case HNA_MESSAGE:
282 m_message.hna.Serialize (i);
283 break;
284 default:
285 NS_ASSERT (false);
286 }
287
288}
289
292{
293 uint32_t size;
297 m_vTime = i.ReadU8 ();
300 m_timeToLive = i.ReadU8 ();
301 m_hopCount = i.ReadU8 ();
304 switch (m_messageType)
305 {
306 case MID_MESSAGE:
307 size += m_message.mid.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
308 break;
309 case HELLO_MESSAGE:
310 size += m_message.hello.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
311 break;
312 case TC_MESSAGE:
313 size += m_message.tc.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
314 break;
315 case HNA_MESSAGE:
316 size += m_message.hna.Deserialize (i, m_messageSize - OLSR_MSG_HEADER_SIZE);
317 break;
318 default:
319 NS_ASSERT (false);
320 }
321 return size;
322}
323
324
325// ---------------- OLSR MID Message -------------------------------
326
329{
330 return this->interfaceAddresses.size () * IPV4_ADDRESS_SIZE;
331}
332
333void
334MessageHeader::Mid::Print (std::ostream &os) const
335{
336 bool first = true;
337 os << " [";
338 for (const auto& iAddr : interfaceAddresses)
339 {
340 if (first)
341 {
342 first = false;
343 }
344 else
345 {
346 os << ", ";
347 }
348 os << iAddr;
349 }
350 os << "]";
351}
352
353void
355{
357
358 for (std::vector<Ipv4Address>::const_iterator iter = this->interfaceAddresses.begin ();
359 iter != this->interfaceAddresses.end (); iter++)
360 {
361 i.WriteHtonU32 (iter->Get ());
362 }
363}
364
367{
369
370 this->interfaceAddresses.clear ();
371 NS_ASSERT (messageSize % IPV4_ADDRESS_SIZE == 0);
372
373 int numAddresses = messageSize / IPV4_ADDRESS_SIZE;
374 this->interfaceAddresses.erase (this->interfaceAddresses.begin (),
375 this->interfaceAddresses.end ());
376 for (int n = 0; n < numAddresses; ++n)
377 {
378 this->interfaceAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
379 }
380 return GetSerializedSize ();
381}
382
383
384
385// ---------------- OLSR HELLO Message -------------------------------
386
389{
390 uint32_t size = 4;
391 for (std::vector<LinkMessage>::const_iterator iter = this->linkMessages.begin ();
392 iter != this->linkMessages.end (); iter++)
393 {
394 const LinkMessage &lm = *iter;
395 size += 4;
397 }
398 return size;
399}
400
401void
402MessageHeader::Hello::Print (std::ostream &os) const
403{
404 os << " Interval: " << +hTime << " (" << EmfToSeconds (hTime) << "s)";
405 os << " Willingness: " << +willingness;
406
407 for (const auto& ilinkMessage : linkMessages)
408 {
409 const LinkMessage &lm = ilinkMessage;
410 os << " Link code: " << +(lm.linkCode);
411 os << " [";
412 bool first = true;
413 for (const auto& neigh_iter : lm.neighborInterfaceAddresses)
414 {
415 if (first)
416 {
417 first = false;
418 }
419 else
420 {
421 os << ", ";
422 }
423 os << neigh_iter;
424 }
425 os << "]";
426 }
427
428}
429
430void
432{
434
435 i.WriteU16 (0); // Reserved
436 i.WriteU8 (this->hTime);
437 i.WriteU8 (this->willingness);
438
439 for (std::vector<LinkMessage>::const_iterator iter = this->linkMessages.begin ();
440 iter != this->linkMessages.end (); iter++)
441 {
442 const LinkMessage &lm = *iter;
443
444 i.WriteU8 (lm.linkCode);
445 i.WriteU8 (0); // Reserved
446
447 // The size of the link message, counted in bytes and measured
448 // from the beginning of the "Link Code" field and until the
449 // next "Link Code" field (or - if there are no more link types
450 // - the end of the message).
452
453 for (std::vector<Ipv4Address>::const_iterator neigh_iter = lm.neighborInterfaceAddresses.begin ();
454 neigh_iter != lm.neighborInterfaceAddresses.end (); neigh_iter++)
455 {
456 i.WriteHtonU32 (neigh_iter->Get ());
457 }
458 }
459}
460
463{
465
466 NS_ASSERT (messageSize >= 4);
467
468 this->linkMessages.clear ();
469
470 uint16_t helloSizeLeft = messageSize;
471
472 i.ReadNtohU16 (); // Reserved
473 this->hTime = i.ReadU8 ();
474 this->willingness = i.ReadU8 ();
475
476 helloSizeLeft -= 4;
477
478 while (helloSizeLeft)
479 {
480 LinkMessage lm;
481 NS_ASSERT (helloSizeLeft >= 4);
482 lm.linkCode = i.ReadU8 ();
483 i.ReadU8 (); // Reserved
484 uint16_t lmSize = i.ReadNtohU16 ();
485 NS_ASSERT ((lmSize - 4) % IPV4_ADDRESS_SIZE == 0);
486 for (int n = (lmSize - 4) / IPV4_ADDRESS_SIZE; n; --n)
487 {
489 }
490 helloSizeLeft -= lmSize;
491 this->linkMessages.push_back (lm);
492 }
493
494 return messageSize;
495}
496
497
498
499// ---------------- OLSR TC Message -------------------------------
500
503{
504 return 4 + this->neighborAddresses.size () * IPV4_ADDRESS_SIZE;
505}
506
507void
508MessageHeader::Tc::Print (std::ostream &os) const
509{
510 os << " Adv. SeqNo: " << ansn;
511 os << " [";
512 bool first = true;
513 for (const auto& iAddr : neighborAddresses)
514 {
515 if (first)
516 {
517 first = false;
518 }
519 else
520 {
521 os << ", ";
522 }
523 os << iAddr;
524 }
525 os << "]";
526}
527
528void
530{
532
533 i.WriteHtonU16 (this->ansn);
534 i.WriteHtonU16 (0); // Reserved
535
536 for (std::vector<Ipv4Address>::const_iterator iter = this->neighborAddresses.begin ();
537 iter != this->neighborAddresses.end (); iter++)
538 {
539 i.WriteHtonU32 (iter->Get ());
540 }
541}
542
545{
547
548 this->neighborAddresses.clear ();
549 NS_ASSERT (messageSize >= 4);
550
551 this->ansn = i.ReadNtohU16 ();
552 i.ReadNtohU16 (); // Reserved
553
554 NS_ASSERT ((messageSize - 4) % IPV4_ADDRESS_SIZE == 0);
555 int numAddresses = (messageSize - 4) / IPV4_ADDRESS_SIZE;
556 this->neighborAddresses.clear ();
557 for (int n = 0; n < numAddresses; ++n)
558 {
559 this->neighborAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
560 }
561
562 return messageSize;
563}
564
565
566// ---------------- OLSR HNA Message -------------------------------
567
570{
571 return 2 * this->associations.size () * IPV4_ADDRESS_SIZE;
572}
573
574void
575MessageHeader::Hna::Print (std::ostream &os) const
576{
577 os << " [";
578 bool first = true;
579 for (const auto& iAssoc : associations)
580 {
581 if (first)
582 {
583 first = false;
584 }
585 else
586 {
587 os << ", ";
588 }
589 os << iAssoc.address << "/" << iAssoc.mask.GetPrefixLength ();
590 }
591 os << "]";
592}
593
594void
596{
598
599 for (size_t n = 0; n < this->associations.size (); ++n)
600 {
601 i.WriteHtonU32 (this->associations[n].address.Get ());
602 i.WriteHtonU32 (this->associations[n].mask.Get ());
603 }
604}
605
608{
610
611 NS_ASSERT (messageSize % (IPV4_ADDRESS_SIZE * 2) == 0);
612 int numAddresses = messageSize / IPV4_ADDRESS_SIZE / 2;
613 this->associations.clear ();
614 for (int n = 0; n < numAddresses; ++n)
615 {
617 Ipv4Mask mask (i.ReadNtohU32 ());
618 this->associations.push_back ((Association) { address, mask});
619 }
620 return messageSize;
621}
622
623}
624} // namespace olsr, ns3
625
iterator in a Buffer instance
Definition: buffer.h:99
uint16_t ReadNtohU16(void)
Definition: buffer.h:946
void WriteU8(uint8_t data)
Definition: buffer.h:869
void WriteU16(uint16_t data)
Definition: buffer.cc:871
uint8_t ReadU8(void)
Definition: buffer.h:1021
void WriteHtonU16(uint16_t data)
Definition: buffer.h:905
void WriteHtonU32(uint32_t data)
Definition: buffer.h:924
uint32_t ReadNtohU32(void)
Definition: buffer.h:970
Protocol header serialization and deserialization.
Definition: header.h:43
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
uint32_t Get(void) const
Get the host-order 32-bit IP address.
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:256
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
This header can store HELP, TC, MID and HNA messages.
Definition: olsr-header.h:158
MessageType m_messageType
The message type.
Definition: olsr-header.h:277
virtual uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:189
static TypeId GetTypeId(void)
Get the type ID.
Definition: olsr-header.cc:173
virtual void Print(std::ostream &os) const
Definition: olsr-header.cc:214
uint8_t m_hopCount
The hop count.
Definition: olsr-header.h:281
Ipv4Address m_originatorAddress
The originator address.
Definition: olsr-header.h:279
uint8_t m_vTime
The validity time.
Definition: olsr-header.h:278
uint8_t m_timeToLive
The time to live.
Definition: olsr-header.h:280
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
Definition: olsr-header.cc:183
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: olsr-header.cc:291
struct ns3::olsr::MessageHeader::@69 m_message
Structure holding the message content.
virtual void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:259
uint16_t m_messageSize
The message size.
Definition: olsr-header.h:283
uint16_t m_messageSequenceNumber
The message sequence number.
Definition: olsr-header.h:282
MessageType
Message type.
Definition: olsr-header.h:164
The basic layout of any packet in OLSR is as follows (omitting IP and UDP headers):
Definition: olsr-header.h:76
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
Definition: olsr-header.cc:124
virtual void Serialize(Buffer::Iterator start) const
Definition: olsr-header.cc:142
static TypeId GetTypeId(void)
Get the type ID.
Definition: olsr-header.cc:114
virtual uint32_t Deserialize(Buffer::Iterator start)
Definition: olsr-header.cc:150
uint16_t m_packetLength
The packet length.
Definition: olsr-header.h:118
virtual void Print(std::ostream &os) const
Definition: olsr-header.cc:136
uint16_t m_packetSequenceNumber
The packet sequence number.
Definition: olsr-header.h:119
virtual uint32_t GetSerializedSize(void) const
Definition: olsr-header.cc:130
#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_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
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Definition: first.py:1
address
Definition: first.py:44
double EmfToSeconds(uint8_t olsrFormat)
Converts a number of seconds in the mantissa/exponent format to a decimal number.
Definition: olsr-header.cc:91
uint8_t SecondsToEmf(double seconds)
Converts a decimal number of seconds to the mantissa/exponent format.
Definition: olsr-header.cc:49
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Definition: olsr.py:1
def start()
Definition: core.py:1853
#define OLSR_MSG_HEADER_SIZE
Definition: olsr-header.cc:29
#define IPV4_ADDRESS_SIZE
Definition: olsr-header.cc:28
#define OLSR_PKT_HEADER_SIZE
Definition: olsr-header.cc:30
#define OLSR_C
Scaling factor used in RFC 3626.
Definition: olsr-header.cc:40
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:462
uint32_t GetSerializedSize(void) const
Returns the expected size of the header.
Definition: olsr-header.cc:388
void Print(std::ostream &os) const
This method is used to print the content of a Hello message.
Definition: olsr-header.cc:402
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:431
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:595
uint32_t GetSerializedSize(void) const
Returns the expected size of the header.
Definition: olsr-header.cc:569
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:607
void Print(std::ostream &os) const
This method is used to print the content of a Hna message.
Definition: olsr-header.cc:575
uint32_t GetSerializedSize(void) const
Returns the expected size of the header.
Definition: olsr-header.cc:328
std::vector< Ipv4Address > interfaceAddresses
Interface Address container.
Definition: olsr-header.h:315
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:354
void Print(std::ostream &os) const
This method is used to print the content of a MID message.
Definition: olsr-header.cc:334
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:366
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:529
void Print(std::ostream &os) const
This method is used to print the content of a Tc message.
Definition: olsr-header.cc:508
uint32_t GetSerializedSize(void) const
Returns the expected size of the header.
Definition: olsr-header.cc:502
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:544