DESERT 3.5.1
Loading...
Searching...
No Matches
uwudp-module.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
40#include "uwudp-module.h"
41
42#include <iostream>
43#include <set>
44
45extern packet_t PT_UWUDP;
46
48 0;
53static class UwUdpPktClass : public PacketHeaderClass
54{
55public:
57 : PacketHeaderClass("PacketHeader/UWUDP", sizeof(hdr_uwudp))
58 {
59 this->bind();
60 bind_offset(&hdr_uwudp::offset_);
61 }
63
67static class UwUdpClass : public TclClass
68{
69public:
71 : TclClass("Module/UW/UDP")
72 {
73 }
74
75 TclObject *
76 create(int, const char *const *)
77 {
78 return (new UwUdp);
79 }
81
83 : portcounter(0)
84 , drop_duplicated_packets_(0)
85 , debug_(0)
86{
87 bind("drop_duplicated_packets_", &drop_duplicated_packets_);
88 bind("debug_", &debug_);
89}
90
92{
93}
94
95int
96UwUdp::command(int argc, const char *const *argv)
97{
98 Tcl &tcl = Tcl::instance();
99 if (argc == 2) {
100 if (strcasecmp(argv[1], "getudpheadersize") == 0) {
101 tcl.resultf("%d", this->getUdpHeaderSize());
102 return TCL_OK;
103 } else if (strcasecmp(argv[1], "printidspkts") == 0) {
104 this->printIdsPkts();
105 return TCL_OK;
106 }
107 }
108 if (argc == 3) {
109 if (strcasecmp(argv[1], "assignPort") == 0) {
110 Module *m = dynamic_cast<Module *>(tcl.lookup(argv[2]));
111 if (!m)
112 return TCL_ERROR;
113 int port = assignPort(m);
114 tcl.resultf("%d", port);
115 return TCL_OK;
116 }
117 }
118 return Module::command(argc, argv);
119}
120
121void
122UwUdp::recv(Packet *p)
123{
124std:
125 cerr << "PortMap::recv() a Packet is sent without source module!"
126 << std::endl;
127 Packet::free(p);
128}
129
130void
131UwUdp::recv(Packet *p, int idSrc)
132{
133 hdr_cmn *ch = HDR_CMN(p);
134 hdr_uwudp *uwudp = HDR_UWUDP(p);
135 hdr_uwip *iph = HDR_UWIP(p);
136
137 if (!ch->error()) {
138 if (ch->direction() == hdr_cmn::UP) {
139
140 map<int, int>::const_iterator iter = id_map.find(uwudp->dport());
141
142 if (iter == id_map.end()) { // Unknown Port Number
143 if (debug_)
144 std::cout << "UwUdp::recv() (dir:UP) "
145 << " dport=" << uwudp->dport()
146 << " portcounter=" << portcounter << std::endl;
147 drop(p, 1, DROP_UNKNOWN_PORT_NUMBER);
148 return;
149 }
150
151 int id = iter->second;
152
153 if (drop_duplicated_packets_ == 1) {
154 map<uint16_t, map_packets_el>::iterator it =
155 map_packets.find(iter->first);
156 if (debug_ > 10)
157 std::cout << ch->uid() << ":"
158 << static_cast<uint16_t>(iph->saddr()) << ":"
159 << iter->first << std::endl;
160 if (it == map_packets.end()) { // Packet to a "new" port.
161 if (debug_ > 10)
162 std::cout << "--> new port" << std::endl;
163 std::set<int> tmp_set_;
164 tmp_set_.insert(ch->uid());
165 map_packets_el tmp_map_el_;
166 tmp_map_el_.insert(pair<uint8_t, std::set<int> >(
167 iph->saddr(), tmp_set_));
168 map_packets.insert(pair<uint16_t, map_packets_el>(
169 iter->first, tmp_map_el_));
170 } else { // Port already used.
171 if (debug_ > 10)
172 std::cout << "--> old port" << std::endl;
173 std::map<uint8_t, std::set<int> >::iterator it2 =
174 it->second.find(iph->saddr());
175 if (it2 == it->second.end()) { // Port already used but
176 // packet from a new source.
177 if (debug_ > 10)
178 std::cout << " --> new source" << std::endl;
179 std::set<int> tmp_set_;
180 tmp_set_.insert(ch->uid());
181 it->second.insert(pair<uint8_t, std::set<int> >(
182 iph->saddr(), tmp_set_));
183 } else { // Port already used and old source.
184 if (debug_ > 10)
185 std::cout << " --> old source" << std::endl;
186 if (it2->second.count(ch->uid()) < 1) {
187 if (debug_ > 10)
188 std::cout << " --> new packet" << std::endl;
189 it2->second.insert(ch->uid());
190 } else { // Packet already received.
191 if (debug_ > 10) {
192 std::cout << " --> duplicated packet"
193 << std::endl;
194 std::cout << " --> dropped" << std::endl;
195 }
197 return;
198 }
199 }
200 }
201 }
202
203 ch->size() -= sizeof(hdr_uwudp);
204 sendUp(id, p);
205 } else { // Direction DOWN.
206 map<int, int>::const_iterator iter = port_map.find(idSrc);
207
208 if (iter == port_map.end()) {
209 std:
210 cerr << "UwUdp::recv() (dir:DOWN) no port assigned to id "
211 << idSrc << ", dropping packet!" << std::endl;
212 Packet::free(p);
213 return;
214 }
215
216 int sport = iter->second;
217 assert(sport > 0 && sport <= portcounter);
218 uwudp->sport() = sport;
219
220 ch->size() += sizeof(hdr_uwudp);
221 sendDown(p);
222 }
223 }
224}
225
226int
228{
229 int id = m->getId();
230
231 // Check that the provided module has not been given a port before
232 if (port_map.find(id) != port_map.end())
233 return TCL_ERROR;
234
235 int newport = ++portcounter;
236
237 port_map[id] = newport;
238 assert(id_map.find(newport) == id_map.end());
239 id_map[newport] = id;
240 assert(id_map.find(newport) != id_map.end());
241
242 if (debug_) {
243 std::cerr << "UwUdp::assignPort() "
244 << " id=" << id << " port=" << newport
245 << " portcounter=" << portcounter << std::endl;
246 }
247 return newport;
248}
Adds the module for UwUdpClass in ns2.
TclObject * create(int, const char *const *)
Adds the header for hdr_uwudp packets in ns2.
UwUdp class is used to manage UWUDP packets, and flows to and from upper modules.
virtual int command(int, const char *const *)
TCL command interpreter.
map< int, int > port_map
Map: value = port; key = id.
virtual int assignPort(Module *)
Associates a module with a port.
map< int, int > id_map
Map: value = id; key = port.
uint16_t portcounter
Counter used to generate new port numbers.
UwUdp()
Constructor of UwUdp class.
static int getUdpHeaderSize()
Returns the size in byte of a hdr_uwudp packet header.
virtual void recv(Packet *)
Performs the reception of packets from upper and lower layers.
std::map< uint8_t, std::set< int > > map_packets_el
std::map< uint16_t, map_packets_el > map_packets
Map used to keep track of the packets received by each port.
int drop_duplicated_packets_
Flat to enable or disable the drop of duplicated packets.
int debug_
Flag to enable or disable dirrefent levels of debug.
void printIdsPkts() const
Prints the IDs of the packet's headers defined by UWUDP.
virtual ~UwUdp()
Destructor of UwUdp class.
hdr_uwip describes UWIP packets.
Definition uwip-module.h:70
uint8_t & saddr()
Reference to the saddr_ variable.
Definition uwip-module.h:95
hdr_uwudp describes UWUDP packets.
static int offset_
Required by the PacketHeaderManager.
uint8_t & sport()
Reference to the sport_ variable.
uint8_t & dport()
Reference to the dport_ variable.
#define HDR_UWIP(P)
Definition uwip-module.h:58
UwUdpClass class_module_uwudp
UwUdpPktClass class_uwudp_pkt
Provides the UWUDP packets header description and the definition of the class UWUDP.
#define HDR_UWUDP(P)
#define DROP_RECEIVED_DUPLICATED_PACKET
Reason for a drop in a UWUDP module.
#define DROP_UNKNOWN_PORT_NUMBER
Reason for a drop in a UWUDP module.