DESERT 3.5.1
Loading...
Searching...
No Matches
uwflooding.cpp
Go to the documentation of this file.
1//
2// Copyright (c) 2017 Regents of the SIGNET lab, University of Padova.
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions
7// are met:
8// 1. Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution.
13// 3. Neither the name of the University of Padova (SIGNET lab) nor the
14// names of its contributors may be used to endorse or promote products
15// derived from this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29
39#include "uwflooding.h"
40
41extern packet_t PT_UWFLOODING;
42
49static class UwFloodingModuleClass : public TclClass
50{
51public:
53 : TclClass("Module/UW/FLOODING")
54 {
55 }
56
57 TclObject *
58 create(int, const char *const *)
59 {
60 return (new UwFlooding());
61 }
63
67static class UwFloodingPktClass : public PacketHeaderClass
68{
69public:
71 : PacketHeaderClass("PacketHeader/FLOODING", sizeof(hdr_uwflooding))
72 {
73 this->bind();
74 bind_offset(&hdr_uwflooding::offset_);
75 }
77
79 : ipAddr_(0)
80 , ttl_(10)
81 , maximum_cache_time_(60)
82 , optimize_(1)
83 , packets_forwarded_(0)
84 , trace_path_(false)
85 , trace_file_path_name_((char *) "trace")
86 , ttl_traffic_map()
87{ // Binding to TCL variables.
88 bind("ttl_", &ttl_);
89 bind("maximum_cache_time_", &maximum_cache_time_);
90 bind("optimize_", &optimize_);
91} /* UwFlooding::UwFlooding */
92
94{
95} /* UwFlooding::~UwFlooding */
96
97int
99{
100 return Module::recvSyncClMsg(m);
101} /* UwFlooding::recvSyncClMsg */
102
103int
105{
106 return Module::recvAsyncClMsg(m);
107} /* UwFlooding::recvAsyncClMsg */
108
109int
110UwFlooding::command(int argc, const char *const *argv)
111{
112 Tcl &tcl = Tcl::instance();
113
114 if (argc == 2) {
115 if (strcasecmp(argv[1], "getpacketsforwarded") == 0) {
116 tcl.resultf("%lu", packets_forwarded_);
117 return TCL_OK;
118 } else if (strcasecmp(argv[1], "getfloodingheadersize") == 0) {
119 tcl.resultf("%d", sizeof(hdr_uwflooding));
120 return TCL_OK;
121 }
122 } else if (argc == 3) {
123 if (strcasecmp(argv[1], "addr") == 0) {
124 ipAddr_ = static_cast<uint8_t>(atoi(argv[2]));
125 if (ipAddr_ == 0) {
126 fprintf(stderr, "0 is not a valid IP address");
127 return TCL_ERROR;
128 }
129 return TCL_OK;
130 } else if (strcasecmp(argv[1], "trace") == 0) {
131 string tmp_ = ((char *) argv[2]);
132 trace_file_path_name_ = new char[tmp_.length() + 1];
135 fprintf(stderr, "Empty string for the trace file name");
136 return TCL_ERROR;
137 }
138 trace_path_ = true;
141 trace_file_path_.close();
142 return TCL_OK;
143 }
144 } else if (argc == 4) {
145 if (strcasecmp(argv[1], "addTtlPerTraffic") == 0) {
146 ttl_traffic_map[static_cast<uint16_t>(atoi(argv[2]))] =
147 static_cast<uint8_t>(atoi(argv[3]));
148 return TCL_OK;
149 }
150 }
151 return Module::command(argc, argv);
152} /* UwFlooding::command */
153
154void
156{
157 hdr_cmn *ch = HDR_CMN(p);
158 hdr_uwip *iph = HDR_UWIP(p);
160
161 if (!ch->error()) {
162 if (ch->direction() == hdr_cmn::UP) {
163 if (trace_path_)
164 this->writePathInTrace(p, "RECV_DTA");
165 if (iph->daddr() == 0) {
166 std::cerr << "Destination address not set." << std::endl;
167 if (trace_path_)
168 this->writePathInTrace(p, "FREE_DTA");
169 Packet::free(p);
170 return;
171 } else if (iph->daddr() == ipAddr_) {
172 flh->ttl()--;
173 if (trace_path_)
174 this->writePathInTrace(p, "SDUP_DTA");
175 sendUp(p);
176 return;
177 } else if (iph->saddr() == ipAddr_) {
178 // cerr << "I am the source: free." << endl;
179 if (trace_path_)
180 this->writePathInTrace(p, "FREE_DTA");
181 Packet::free(p);
182 return;
183 } else if (iph->daddr() == UWIP_BROADCAST) {
184 // sendUp always: the destination is in broadcast.
185 ch->size() -= sizeof(hdr_uwflooding);
186 if (trace_path_)
187 this->writePathInTrace(p, "SDUP_DTA");
188 sendUp(p->copy());
189
190 // SendDown
191 ch->direction() = hdr_cmn::DOWN;
192 ch->prev_hop_ = ipAddr_;
193 ch->next_hop() = UWIP_BROADCAST;
194 flh->ttl()--;
195 ch->size() += sizeof(hdr_uwflooding);
196 if (flh->ttl() <= 0) {
197 if (trace_path_)
198 this->writePathInTrace(p, "DROP_TTL");
200 return;
201 } else {
202 if (optimize_) {
203 map_forwarded_packets::iterator it2 =
204 my_forwarded_packets_.find(iph->saddr());
205 if (it2 != my_forwarded_packets_.end()) {
206 map_packets::iterator it3 =
207 it2->second.find(ch->uid());
208
209 if (it3 == it2->second.end()) { // Known source and
210 // new packet -> add
211 // it to the map and
212 // forward.
213 it2->second.insert(std::pair<uint16_t, double>(
214 ch->uid(), ch->timestamp()));
216 if (trace_path_)
217 this->writePathInTrace(p, "FRWD_DTA");
218 sendDown(p);
219 return;
220 } else if (Scheduler::instance().clock() -
221 it3->second >
222 maximum_cache_time_) { // Packet already
223 // processed by not
224 // valid maximum
225 // cache timer ->
226 // update the cache
227 // time and forward.
228 it3->second = Scheduler::instance().clock();
230 if (trace_path_)
231 this->writePathInTrace(p, "FRWD_DTA");
232 sendDown(p);
233 return;
234 } else {
235 if (trace_path_)
236 this->writePathInTrace(p, "FREE_DTA");
237 Packet::free(p);
238 return;
239 }
240 } else {
241 std::map<uint16_t, double> tmp_map;
242 tmp_map.insert(std::pair<uint16_t, double>(
243 ch->uid(), Scheduler::instance().clock()));
245 std::pair<uint8_t, map_packets>(
246 iph->saddr(), tmp_map));
248 if (trace_path_)
249 this->writePathInTrace(p, "FRWD_DTA");
250 sendDown(p);
251 return;
252 }
253 } else {
255 if (trace_path_)
256 this->writePathInTrace(p, "FRWD_DTA");
257 sendDown(p);
258 return;
259 }
260 }
261 } else if (iph->daddr() != ipAddr_) {
262 // SendDown
263 ch->direction() = hdr_cmn::DOWN;
264 ch->prev_hop_ = ipAddr_;
265 ch->next_hop() = UWIP_BROADCAST;
266 flh->ttl()--;
267 if (flh->ttl() <= 0) {
268 if (trace_path_)
269 this->writePathInTrace(p, "DROP_TTL");
271 return;
272 } else {
273 if (optimize_) {
274 map_forwarded_packets::iterator it2 =
275 my_forwarded_packets_.find(iph->saddr());
276 if (it2 != my_forwarded_packets_.end()) {
277 map_packets::iterator it3 =
278 it2->second.find(ch->uid());
279
280 if (it3 == it2->second.end()) { // Known source and
281 // new packet -> add
282 // it to the map and
283 // forward.
284 it2->second.insert(std::pair<uint16_t, double>(
285 ch->uid(), ch->timestamp()));
287 if (trace_path_)
288 this->writePathInTrace(p, "FRWD_DTA");
289 sendDown(p);
290 return;
291 } else if (Scheduler::instance().clock() -
292 it3->second >
293 maximum_cache_time_) { // Packet already
294 // processed by not
295 // valid maximum
296 // cache timer ->
297 // update the cache
298 // time and forward.
299 it3->second = Scheduler::instance().clock();
301 if (trace_path_)
302 this->writePathInTrace(p, "FRWD_DTA");
303 sendDown(p);
304 return;
305 } else {
306 if (trace_path_)
307 this->writePathInTrace(p, "FREE_DTA");
308 Packet::free(p);
309 return;
310 }
311 } else {
312 std::map<uint16_t, double> tmp_map;
313 tmp_map.insert(std::pair<uint16_t, double>(
314 ch->uid(), Scheduler::instance().clock()));
316 std::pair<uint8_t, map_packets>(
317 iph->saddr(), tmp_map));
319 if (trace_path_)
320 this->writePathInTrace(p, "FRWD_DTA");
321 sendDown(p);
322 return;
323 }
324 } else {
325 if (trace_path_)
326 this->writePathInTrace(p, "FRWD_DTA");
327 sendDown(p);
328 return;
329 }
330 }
331 } else {
332 cerr << "State machine ERROR." << endl;
333 if (trace_path_)
334 this->writePathInTrace(p, "FREE_DTA");
335 Packet::free(p);
336 return;
337 }
338 } else if (ch->direction() == hdr_cmn::DOWN) {
339 if (trace_path_)
340 this->writePathInTrace(p, "RECV_DTA");
341 if (iph->daddr() == 0) {
342 std::cerr << "Destination address equals to 0." << std::endl;
343 if (trace_path_)
344 this->writePathInTrace(p, "FREE_DTA");
345 Packet::free(p);
346 return;
347 }
348 if (iph->daddr() == ipAddr_) {
349 if (trace_path_)
350 this->writePathInTrace(p, "SDUP_DTA");
351 sendUp(p);
352 return;
353 } else { // iph->daddr() != ipAddr_
354 ch->prev_hop_ = ipAddr_;
355 ch->next_hop() = UWIP_BROADCAST;
356 ch->size() += sizeof(hdr_uwflooding);
357 flh->ttl() = getTTL(p);
358 if (trace_path_)
359 this->writePathInTrace(p, "FRWD_DTA");
360 sendDown(p);
361 return;
362 }
363 } else {
364 cerr << "Direction different from UP or DOWN." << endl;
365 if (trace_path_)
366 this->writePathInTrace(p, "FREE_DTA");
367 Packet::free(p);
368 return;
369 }
370 } else {
371 if (trace_path_)
372 this->writePathInTrace(p, "FREE_DTA");
373 Packet::free(p);
374 return;
375 }
376} /* UwFlooding::recv */
377
378uint8_t UwFlooding::getTTL(Packet* p) const
379{
381 auto it = ttl_traffic_map.find(uwcbrh->traffic_type());
382 if(it != ttl_traffic_map.end()) {
383 return it->second;
384 }
385 return ttl_;
386}
387
388void
389UwFlooding::writePathInTrace(const Packet *p, const string &_info)
390{
391 hdr_uwip *iph = HDR_UWIP(p);
392 hdr_cmn *ch = HDR_CMN(p);
394
395 trace_file_path_.open(trace_file_path_name_, fstream::app);
396 osstream_.clear();
397 osstream_.str("");
398 osstream_ << _info;
399 osstream_ << '\t';
400 osstream_ << Scheduler::instance().clock();
401 osstream_ << '\t';
402 osstream_ << static_cast<uint32_t>(ch->uid() & 0x0000ffff);
403 osstream_ << '\t';
405 osstream_ << '\t';
406 osstream_ << static_cast<uint32_t>(ch->prev_hop_ & 0x000000ff);
407 osstream_ << '\t';
408 osstream_ << static_cast<uint32_t>(ch->next_hop() & 0x000000ff);
409 osstream_ << '\t';
411 osstream_ << '\t';
413 osstream_ << '\t';
414 osstream_ << ch->direction();
415 osstream_ << '\t';
416 osstream_ << ch->ptype();
417 trace_file_path_ << osstream_.str() << endl;
418 trace_file_path_.close();
419} /* UwFlooding::writePathInTrace */
420
421string
422UwFlooding::printIP(const nsaddr_t &ip_)
423{
425 out << ((ip_ & 0xff000000) >> 24);
426 out << ".";
427 out << ((ip_ & 0x00ff0000) >> 16);
428 out << ".";
429 out << ((ip_ & 0x0000ff00) >> 8);
430 out << ".";
431 out << ((ip_ & 0x000000ff));
432 return out.str();
433} /* UwFlooding::printIP */
Adds the module for SunIPRoutingSink in ns2.
TclObject * create(int, const char *const *)
Adds the header for hdr_uwflooding packets in ns2.
UwFlooding class is used to represent the routing layer of a node.
Definition uwflooding.h:75
UwFlooding()
Constructor of UwFlooding class.
uint8_t ipAddr_
Definition uwflooding.h:158
long packets_forwarded_
Number of packets forwarded by this module.
Definition uwflooding.h:163
static string printIP(const nsaddr_t &)
Return a string with an IP in the classic form "x.x.x.x" converting an ns2 nsaddr_t address.
virtual int command(int, const char *const *)
TCL command interpreter.
virtual int recvAsyncClMsg(ClMessage *)
Cross-Layer messages asynchronous interpreter.
virtual void recv(Packet *)
Performs the reception of packets from upper and lower layers.
ofstream trace_file_path_
Ofstream used to write the path trace file in the disk.
Definition uwflooding.h:170
double maximum_cache_time_
Validity time of a packet entry.
Definition uwflooding.h:160
uint8_t getTTL(Packet *p) const
Get the value of the TTL.
char * trace_file_path_name_
Name of the trace file that contains the list of paths of the data packets received.
Definition uwflooding.h:167
virtual ~UwFlooding()
Destructor of UwFlooding class.
std::map< uint16_t, uint8_t > ttl_traffic_map
Map with ttl per traffic.
Definition uwflooding.h:183
int optimize_
Flag used to enable the mechanism to drop packets processed twice.
Definition uwflooding.h:161
bool trace_path_
Flag used to enable or disable the path trace file for nodes,.
Definition uwflooding.h:164
virtual int recvSyncClMsg(ClMessage *)
Cross-Layer messages synchronous interpreter.
virtual void writePathInTrace(const Packet *, const string &)
Writes in the Path Trace file the path contained in the Packet.
ostringstream osstream_
Used to convert to string.
Definition uwflooding.h:172
map_forwarded_packets my_forwarded_packets_
Map of the packet forwarded.
Definition uwflooding.h:181
int ttl_
Time to leave of the UWFLOODING packets.
Definition uwflooding.h:159
hdr_uwcbr describes UWCBR packets.
hdr_uwflooding describes packets used by UWFLOODING.
static int offset_
Required by the PacketHeaderManager.
hdr_uwip describes UWIP packets.
Definition uwip-module.h:70
#define HDR_UWCBR(p)
UwFloodingPktClass class_uwflooding_pkt
UwFloodingModuleClass class_module_uwflooding
Flooding based routing protocol.
#define TTL_EQUALS_TO_ZERO
Reason for a drop in a UWFLOODING module.
Definition uwflooding.h:43
static const uint8_t UWIP_BROADCAST
Variable used to represent a broadcast UWIP.
Definition uwip-module.h:62
#define HDR_UWIP(P)
Definition uwip-module.h:58