A Discrete-Event Network Simulator
API
ie-dot11s-preq.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008,2009 IITP RAS
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Kirill Andreev <andreev@iitp.ru>
18  */
19 
20 #include "ie-dot11s-preq.h"
21 
22 #include "ns3/address-utils.h"
23 #include "ns3/assert.h"
24 #include "ns3/packet.h"
25 
26 namespace ns3
27 {
28 namespace dot11s
29 {
30 /*************************
31  * DestinationAddressUnit
32  ************************/
34  : m_do(false),
35  m_rf(false),
36  m_usn(false),
37  m_destinationAddress(Mac48Address()),
38  m_destSeqNumber(0)
39 {
40 }
41 
42 void
43 DestinationAddressUnit::SetFlags(bool doFlag, bool rfFlag, bool usnFlag)
44 {
45  m_do = doFlag;
46  m_rf = rfFlag;
47  m_usn = usnFlag;
48 }
49 
50 void
52 {
53  m_destSeqNumber = dest_seq_number;
54  if (m_destSeqNumber != 0)
55  {
56  m_usn = true;
57  }
58 }
59 
60 void
62 {
63  m_destinationAddress = dest_address;
64 }
65 
66 bool
68 {
69  return m_do;
70 }
71 
72 bool
74 {
75  return m_rf;
76 }
77 
78 bool
80 {
81  return m_usn;
82 }
83 
84 uint32_t
86 {
87  return m_destSeqNumber;
88 }
89 
92 {
93  return m_destinationAddress;
94 }
95 
96 /********************************
97  * IePreq
98  *******************************/
100 {
101 }
102 
104  : m_maxSize(32),
105  m_flags(0),
106  m_hopCount(0),
107  m_ttl(0),
108  m_preqId(0),
109  m_originatorAddress(Mac48Address::GetBroadcast()),
110  m_originatorSeqNumber(0),
111  m_lifetime(0),
112  m_metric(0),
113  m_destCount(0)
114 {
115 }
116 
119 {
120  return IE_PREQ;
121 }
122 
123 void
125 {
126  m_flags |= 1 << 1;
127 }
128 
129 void
131 {
132  m_flags |= 1 << 2;
133 }
134 
135 void
136 IePreq::SetHopcount(uint8_t hopcount)
137 {
138  m_hopCount = hopcount;
139 }
140 
141 void
142 IePreq::SetTTL(uint8_t ttl)
143 {
144  m_ttl = ttl;
145 }
146 
147 void
148 IePreq::SetPreqID(uint32_t preq_id)
149 {
150  m_preqId = preq_id;
151 }
152 
153 void
154 IePreq::SetMetric(uint32_t metric)
155 {
156  m_metric = metric;
157 }
158 
159 void
161 {
162  m_originatorAddress = originator_address;
163 }
164 
165 void
166 IePreq::SetOriginatorSeqNumber(uint32_t originator_seq_number)
167 {
168  m_originatorSeqNumber = originator_seq_number;
169 }
170 
171 void
172 IePreq::SetLifetime(uint32_t lifetime)
173 {
174  m_lifetime = lifetime;
175 }
176 
177 void
178 IePreq::SetDestCount(uint8_t dest_count)
179 {
180  m_destCount = dest_count;
181 }
182 
183 bool
185 {
186  return (m_flags & (1 << 1));
187 }
188 
189 bool
191 {
192  return (m_flags & (1 << 2));
193 }
194 
195 uint8_t
197 {
198  return m_hopCount;
199 }
200 
201 uint8_t
203 {
204  return m_ttl;
205 }
206 
207 uint32_t
209 {
210  return m_preqId;
211 }
212 
213 uint32_t
215 {
216  return m_metric;
217 }
218 
221 {
222  return m_originatorAddress;
223 }
224 
225 uint32_t
227 {
228  return m_originatorSeqNumber;
229 }
230 
231 uint32_t
233 {
234  return m_lifetime;
235 }
236 
237 uint8_t
239 {
240  return m_destCount;
241 }
242 
243 void
245 {
246  m_ttl--;
247  m_hopCount++;
248 }
249 
250 void
251 IePreq::IncrementMetric(uint32_t metric)
252 {
253  m_metric += metric;
254 }
255 
256 void
258 {
259  i.WriteU8(m_flags);
260  i.WriteU8(m_hopCount);
261  i.WriteU8(m_ttl);
267  i.WriteU8(m_destCount);
268  int written = 0;
269  for (std::vector<Ptr<DestinationAddressUnit>>::const_iterator j = m_destinations.begin();
270  j != m_destinations.end();
271  j++)
272  {
273  uint8_t flags = 0;
274  if ((*j)->IsDo())
275  {
276  flags |= 1 << 0;
277  }
278  if ((*j)->IsRf())
279  {
280  flags |= 1 << 1;
281  }
282  if ((*j)->IsUsn())
283  {
284  flags |= 1 << 2;
285  }
286  i.WriteU8(flags);
287  WriteTo(i, (*j)->GetDestinationAddress());
288  i.WriteHtolsbU32((*j)->GetDestSeqNumber());
289  written++;
290  if (written > m_maxSize)
291  {
292  break;
293  }
294  }
295 }
296 
297 uint16_t
299 {
301  m_flags = i.ReadU8();
302  m_hopCount = i.ReadU8();
303  m_ttl = i.ReadU8();
304  m_preqId = i.ReadLsbtohU32();
308  m_metric = i.ReadLsbtohU32();
309  m_destCount = i.ReadU8();
310  for (int j = 0; j < m_destCount; j++)
311  {
312  Ptr<DestinationAddressUnit> new_element = Create<DestinationAddressUnit>();
313  bool doFlag = false;
314  bool rfFlag = false;
315  bool usnFlag = false;
316  uint8_t flags = i.ReadU8();
317  if (flags & (1 << 0))
318  {
319  doFlag = true;
320  }
321  if (flags & (1 << 1))
322  {
323  rfFlag = true;
324  }
325  if (flags & (1 << 2))
326  {
327  usnFlag = true;
328  }
329  new_element->SetFlags(doFlag, rfFlag, usnFlag);
330  Mac48Address addr;
331  ReadFrom(i, addr);
332  new_element->SetDestinationAddress(addr);
333  new_element->SetDestSeqNumber(i.ReadLsbtohU32());
334  m_destinations.push_back(new_element);
335  NS_ASSERT(28 + j * 11 < length);
336  }
337  return i.GetDistanceFrom(start);
338 }
339 
340 uint16_t
342 {
343  uint16_t retval = 1 // Flags
344  + 1 // Hopcount
345  + 1 // TTL
346  + 4 // PREQ ID
347  + 6 // Source address (originator)
348  + 4 // Originator seqno
349  + 4 // Lifetime
350  + 4 // metric
351  + 1; // destination count
352  if (m_destCount > m_maxSize)
353  {
354  retval += (m_maxSize * 11);
355  }
356  else
357  {
358  retval += (m_destCount * 11);
359  }
360  return retval;
361 }
362 
363 void
364 IePreq::Print(std::ostream& os) const
365 {
366  os << "PREQ=(originator address=" << m_originatorAddress << ", TTL=" << (uint16_t)m_ttl
367  << ", hop count=" << (uint16_t)m_hopCount << ", metric=" << m_metric
368  << ", seqno=" << m_originatorSeqNumber << ", lifetime=" << m_lifetime
369  << ", preq ID=" << m_preqId << ", Destinations=(";
370  for (int j = 0; j < m_destCount; j++)
371  {
372  os << m_destinations[j]->GetDestinationAddress();
373  }
374  os << ")";
375 }
376 
377 std::vector<Ptr<DestinationAddressUnit>>
379 {
380  return m_destinations;
381 }
382 
383 void
385  bool rfFlag,
386  Mac48Address dest_address,
387  uint32_t dest_seq_number)
388 {
389  for (std::vector<Ptr<DestinationAddressUnit>>::const_iterator i = m_destinations.begin();
390  i != m_destinations.end();
391  i++)
392  {
393  if ((*i)->GetDestinationAddress() == dest_address)
394  {
395  return;
396  }
397  }
399  Ptr<DestinationAddressUnit> new_element = Create<DestinationAddressUnit>();
400  new_element->SetFlags(doFlag, rfFlag, (dest_seq_number == 0));
401  new_element->SetDestinationAddress(dest_address);
402  new_element->SetDestSeqNumber(dest_seq_number);
403  m_destinations.push_back(new_element);
404  m_destCount++;
405 }
406 
407 void
409 {
410  for (std::vector<Ptr<DestinationAddressUnit>>::iterator i = m_destinations.begin();
411  i != m_destinations.end();
412  i++)
413  {
414  if ((*i)->GetDestinationAddress() == dest_address)
415  {
416  m_destinations.erase(i);
417  m_destCount--;
418  break;
419  }
420  }
421 }
422 
423 void
425 {
426  for (std::vector<Ptr<DestinationAddressUnit>>::iterator j = m_destinations.begin();
427  j != m_destinations.end();
428  j++)
429  {
430  (*j) = nullptr;
431  }
432  m_destinations.clear();
433  m_destCount = 0;
434 }
435 
436 bool
438 {
439  return (a.m_do == b.m_do && a.m_rf == b.m_rf && a.m_usn == b.m_usn &&
442 }
443 
444 bool
445 operator==(const IePreq& a, const IePreq& b)
446 {
447  bool ok = (a.m_flags == b.m_flags && a.m_hopCount == b.m_hopCount && a.m_ttl == b.m_ttl &&
450  a.m_metric == b.m_metric && a.m_destCount == b.m_destCount);
451 
452  if (!ok)
453  {
454  return false;
455  }
456  if (a.m_destinations.size() != b.m_destinations.size())
457  {
458  return false;
459  }
460  for (size_t i = 0; i < a.m_destinations.size(); ++i)
461  {
462  if (!(*(PeekPointer(a.m_destinations[i])) == *(PeekPointer(b.m_destinations[i]))))
463  {
464  return false;
465  }
466  }
467  return true;
468 }
469 
470 bool
472 {
473  if (m_originatorAddress != originator)
474  {
475  return false;
476  }
477  if (m_destinations[0]->GetDestinationAddress() == Mac48Address::GetBroadcast())
478  {
479  return false;
480  }
481  // -fstrict-overflow sensitive, see bug 1868
482  if (GetInformationFieldSize() > 255 - 11)
483  {
484  return false;
485  }
486  return true;
487 }
488 
489 bool
491 {
492  // -fstrict-overflow sensitive, see bug 1868
493  return (GetInformationFieldSize() > 255 - 11);
494 }
495 
496 std::ostream&
497 operator<<(std::ostream& os, const IePreq& a)
498 {
499  a.Print(os);
500  return os;
501 }
502 } // namespace dot11s
503 } // namespace ns3
iterator in a Buffer instance
Definition: buffer.h:100
uint8_t ReadU8()
Definition: buffer.h:1027
void WriteU8(uint8_t data)
Definition: buffer.h:881
void WriteHtolsbU32(uint32_t data)
Definition: buffer.cc:913
uint32_t GetDistanceFrom(const Iterator &o) const
Definition: buffer.cc:783
uint32_t ReadLsbtohU32()
Definition: buffer.cc:1079
an EUI-48 address
Definition: mac48-address.h:46
static Mac48Address GetBroadcast()
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
Describes an address unit in PREQ information element See 7.3.2.96 for more details.
bool IsUsn() const
Is USN function.
uint32_t GetDestSeqNumber() const
Get destination sequence number.
bool IsRf() const
is RF function
void SetDestSeqNumber(uint32_t dest_seq_number)
Set destination sequence number.
Mac48Address m_destinationAddress
destination address
uint32_t m_destSeqNumber
destination sequence number
Mac48Address GetDestinationAddress() const
Get destination address function.
void SetFlags(bool doFlag, bool rfFlag, bool usnFlag)
Set flags function.
void SetDestinationAddress(Mac48Address dest_address)
Set destination address function.
bool IsDo() const
Is do function.
See 7.3.2.96 of 802.11s draft 2.07.
uint32_t GetOriginatorSeqNumber() const
Get originator sequence number value.
uint32_t m_originatorSeqNumber
originator sequence number
void DelDestinationAddressElement(Mac48Address dest_address)
Delete a destination address unit by destination.
uint8_t m_destCount
destination count
void SetHopcount(uint8_t hopcount)
Set number of hops from originator to mesh STA transmitting this element.
uint8_t GetDestCount() const
Get destination count.
void SetNeedNotPrep()
Set Proactive PREP subfield to off.
bool IsUnicastPreq() const
Is unicast PREQ function.
uint16_t GetInformationFieldSize() const override
Length of serialized information (i.e., the length of the body of the IE, not including the Element I...
uint8_t GetHopCount() const
Get hop count value.
void SetUnicastPreq()
Set flag indicating that PREQ is unicast.
std::vector< Ptr< DestinationAddressUnit > > GetDestinationList()
Get all destinations, which are stored in PREQ:
void SetOriginatorSeqNumber(uint32_t originator_seq_number)
Set originator sequence number.
uint32_t GetMetric() const
Get metric value.
void SetTTL(uint8_t ttl)
Set remaining number of hops allowed for this element.
uint32_t m_preqId
PREQ ID.
void SetOriginatorAddress(Mac48Address originator_address)
Set originator address value.
void Print(std::ostream &os) const override
Generate human-readable form of IE.
Mac48Address GetOriginatorAddress() const
Get originator address value.
void DecrementTtl()
Handle TTL.
uint32_t GetPreqID() const
Get path discovery id field.
uint8_t m_hopCount
hop count
void ClearDestinationAddressElements()
Clear PREQ: remove all destinations.
void SetDestCount(uint8_t dest_count)
Set destination count value.
void SetMetric(uint32_t metric)
Set metric value.
bool IsFull() const
Is full function.
uint8_t m_flags
flags
WifiInformationElementId ElementId() const override
Get the wifi information element ID.
uint16_t DeserializeInformationField(Buffer::Iterator i, uint16_t length) override
Deserialize information (i.e., the body of the IE, not including the Element ID and length octets)
bool MayAddAddress(Mac48Address originator)
Checks that preq's originator address equals to originator, and this preq is not proactive.
uint32_t m_metric
metric
void SerializeInformationField(Buffer::Iterator i) const override
Serialize information (i.e., the body of the IE, not including the Element ID and length octets)
uint8_t GetTtl() const
Get TTL value.
void SetPreqID(uint32_t id)
Set path discovery id field.
void IncrementMetric(uint32_t metric)
Handle Metric:
Mac48Address m_originatorAddress
originator address
uint8_t m_maxSize
how many destinations we support
uint32_t GetLifetime() const
Get lifetime value.
std::vector< Ptr< DestinationAddressUnit > > m_destinations
the destinations
void AddDestinationAddressElement(bool doFlag, bool rfFlag, Mac48Address dest_address, uint32_t dest_seq_number)
Add a destination address unit: flags, destination and sequence number.
bool IsNeedNotPrep() const
Check whether Proactive PREP subfield to off.
void SetLifetime(uint32_t lifetime)
Set lifetime in TUs for the forwarding information to be considered valid.
uint32_t m_lifetime
lifetime
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
bool operator==(const MeshHeader &a, const MeshHeader &b)
std::ostream & operator<<(std::ostream &os, const IeBeaconTiming &a)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void WriteTo(Buffer::Iterator &i, Ipv4Address ad)
Write an Ipv4Address to a Buffer.
uint8_t WifiInformationElementId
This type is used to represent an Information Element ID.
void ReadFrom(Buffer::Iterator &i, Ipv4Address &ad)
Read an Ipv4Address from a Buffer.
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:488
#define IE_PREQ