A Discrete-Event Network Simulator
API
ipv6-end-point-demux.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2007-2009 Strasbourg University
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: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
19 */
20
22#include "ipv6-end-point.h"
23#include "ns3/log.h"
24
25namespace ns3 {
26
27NS_LOG_COMPONENT_DEFINE ("Ipv6EndPointDemux");
28
30 : m_ephemeral (49152),
31 m_portFirst (49152),
32 m_portLast (65535)
33{
34 NS_LOG_FUNCTION (this);
35}
36
38{
39 NS_LOG_FUNCTION (this);
40 for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
41 {
42 Ipv6EndPoint *endPoint = *i;
43 delete endPoint;
44 }
45 m_endPoints.clear ();
46}
47
49{
50 NS_LOG_FUNCTION (this << port);
51 for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
52 {
53 if ((*i)->GetLocalPort () == port)
54 {
55 return true;
56 }
57 }
58 return false;
59}
60
62{
63 NS_LOG_FUNCTION (this << addr << port);
64 for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
65 {
66 if ((*i)->GetLocalPort () == port &&
67 (*i)->GetLocalAddress () == addr &&
68 (*i)->GetBoundNetDevice () == boundNetDevice)
69 {
70 return true;
71 }
72 }
73 return false;
74}
75
77{
78 NS_LOG_FUNCTION (this);
79 uint16_t port = AllocateEphemeralPort ();
80 if (port == 0)
81 {
82 NS_LOG_WARN ("Ephemeral port allocation failed.");
83 return 0;
84 }
86 m_endPoints.push_back (endPoint);
87 NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
88 return endPoint;
89}
90
92{
93 NS_LOG_FUNCTION (this << address);
94 uint16_t port = AllocateEphemeralPort ();
95 if (port == 0)
96 {
97 NS_LOG_WARN ("Ephemeral port allocation failed.");
98 return 0;
99 }
100 Ipv6EndPoint *endPoint = new Ipv6EndPoint (address, port);
101 m_endPoints.push_back (endPoint);
102 NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
103 return endPoint;
104}
105
107{
108 NS_LOG_FUNCTION (this << boundNetDevice << port);
109
110 return Allocate (boundNetDevice, Ipv6Address::GetAny (), port);
111}
112
114{
115 NS_LOG_FUNCTION (this << boundNetDevice << address << port);
116 if (LookupLocal (boundNetDevice, address, port) || LookupLocal (0, address, port))
117 {
118 NS_LOG_WARN ("Duplicated endpoint.");
119 return 0;
120 }
121 Ipv6EndPoint *endPoint = new Ipv6EndPoint (address, port);
122 m_endPoints.push_back (endPoint);
123 NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
124 return endPoint;
125}
126
128 Ipv6Address localAddress, uint16_t localPort,
129 Ipv6Address peerAddress, uint16_t peerPort)
130{
131 NS_LOG_FUNCTION (this << boundNetDevice << localAddress << localPort << peerAddress << peerPort);
132 for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
133 {
134 if ((*i)->GetLocalPort () == localPort &&
135 (*i)->GetLocalAddress () == localAddress &&
136 (*i)->GetPeerPort () == peerPort &&
137 (*i)->GetPeerAddress () == peerAddress &&
138 ((*i)->GetBoundNetDevice () == boundNetDevice || (*i)->GetBoundNetDevice () == 0))
139 {
140 NS_LOG_WARN ("Duplicated endpoint.");
141 return 0;
142 }
143 }
144 Ipv6EndPoint *endPoint = new Ipv6EndPoint (localAddress, localPort);
145 endPoint->SetPeer (peerAddress, peerPort);
146 m_endPoints.push_back (endPoint);
147
148 NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
149
150 return endPoint;
151}
152
154{
155 NS_LOG_FUNCTION (this);
156 for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
157 {
158 if (*i == endPoint)
159 {
160 delete endPoint;
161 m_endPoints.erase (i);
162 break;
163 }
164 }
165}
166
167/*
168 * If we have an exact match, we return it.
169 * Otherwise, if we find a generic match, we return it.
170 * Otherwise, we return 0.
171 */
173 Ipv6Address saddr, uint16_t sport,
174 Ptr<Ipv6Interface> incomingInterface)
175{
176 NS_LOG_FUNCTION (this << daddr << dport << saddr << sport << incomingInterface);
177
178 EndPoints retval1; /* Matches exact on local port, wildcards on others */
179 EndPoints retval2; /* Matches exact on local port/adder, wildcards on others */
180 EndPoints retval3; /* Matches all but local address */
181 EndPoints retval4; /* Exact match on all 4 */
182
183 NS_LOG_DEBUG ("Looking up endpoint for destination address " << daddr);
184 for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
185 {
186 Ipv6EndPoint* endP = *i;
187
188 NS_LOG_DEBUG ("Looking at endpoint dport=" << endP->GetLocalPort ()
189 << " daddr=" << endP->GetLocalAddress ()
190 << " sport=" << endP->GetPeerPort ()
191 << " saddr=" << endP->GetPeerAddress ());
192
193 if (!endP->IsRxEnabled ())
194 {
195 NS_LOG_LOGIC ("Skipping endpoint " << &endP
196 << " because endpoint can not receive packets");
197 continue;
198 }
199
200 if (endP->GetLocalPort () != dport)
201 {
202 NS_LOG_LOGIC ("Skipping endpoint " << &endP
203 << " because endpoint dport "
204 << endP->GetLocalPort ()
205 << " does not match packet dport " << dport);
206 continue;
207 }
208
209 if (endP->GetBoundNetDevice ())
210 {
211 if (!incomingInterface)
212 {
213 continue;
214 }
215 if (endP->GetBoundNetDevice () != incomingInterface->GetDevice ())
216 {
217 NS_LOG_LOGIC ("Skipping endpoint " << &endP
218 << " because endpoint is bound to specific device and"
219 << endP->GetBoundNetDevice ()
220 << " does not match packet device " << incomingInterface->GetDevice ());
221 continue;
222 }
223 }
224
225 /* Ipv6Address incomingInterfaceAddr = incomingInterface->GetAddress (); */
226 NS_LOG_DEBUG ("dest addr " << daddr);
227
228 bool localAddressMatchesWildCard = endP->GetLocalAddress () == Ipv6Address::GetAny ();
229 bool localAddressMatchesExact = endP->GetLocalAddress () == daddr;
230 bool localAddressMatchesAllRouters = endP->GetLocalAddress () == Ipv6Address::GetAllRoutersMulticast ();
231
232 /* if no match here, keep looking */
233 if (!(localAddressMatchesExact || localAddressMatchesWildCard))
234 {
235 continue;
236 }
237 bool remotePeerMatchesExact = endP->GetPeerPort () == sport;
238 bool remotePeerMatchesWildCard = endP->GetPeerPort () == 0;
239 bool remoteAddressMatchesExact = endP->GetPeerAddress () == saddr;
240 bool remoteAddressMatchesWildCard = endP->GetPeerAddress () == Ipv6Address::GetAny ();
241
242 /* If remote does not match either with exact or wildcard,i
243 skip this one */
244 if (!(remotePeerMatchesExact || remotePeerMatchesWildCard))
245 {
246 continue;
247 }
248 if (!(remoteAddressMatchesExact || remoteAddressMatchesWildCard))
249 {
250 continue;
251 }
252
253 /* Now figure out which return list to add this one to */
254 if (localAddressMatchesWildCard
255 && remotePeerMatchesWildCard
256 && remoteAddressMatchesWildCard)
257 { /* Only local port matches exactly */
258 retval1.push_back (endP);
259 }
260 if ((localAddressMatchesExact || (localAddressMatchesAllRouters))
261 && remotePeerMatchesWildCard
262 && remoteAddressMatchesWildCard)
263 { /* Only local port and local address matches exactly */
264 retval2.push_back (endP);
265 }
266 if (localAddressMatchesWildCard
267 && remotePeerMatchesExact
268 && remoteAddressMatchesExact)
269 { /* All but local address */
270 retval3.push_back (endP);
271 }
272 if (localAddressMatchesExact
273 && remotePeerMatchesExact
274 && remoteAddressMatchesExact)
275 { /* All 4 match */
276 retval4.push_back (endP);
277 }
278 }
279
280 // Here we find the most exact match
281 EndPoints retval;
282 if (!retval4.empty ()) retval = retval4;
283 else if (!retval3.empty ()) retval = retval3;
284 else if (!retval2.empty ()) retval = retval2;
285 else retval = retval1;
286
287 NS_ABORT_MSG_IF (retval.size () > 1, "Too many endpoints - perhaps you created too many sockets without binding them to different NetDevices.");
288 return retval; // might be empty if no matches
289}
290
291Ipv6EndPoint* Ipv6EndPointDemux::SimpleLookup (Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport)
292{
293 uint32_t genericity = 3;
294 Ipv6EndPoint *generic = 0;
295
296 for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
297 {
298 uint32_t tmp = 0;
299
300 if ((*i)->GetLocalPort () != dport)
301 {
302 continue;
303 }
304
305 if ((*i)->GetLocalAddress () == dst && (*i)->GetPeerPort () == sport
306 && (*i)->GetPeerAddress () == src)
307 {
308 /* this is an exact match. */
309 return *i;
310 }
311
312 if ((*i)->GetLocalAddress () == Ipv6Address::GetAny ())
313 {
314 tmp++;
315 }
316
317 if ((*i)->GetPeerAddress () == Ipv6Address::GetAny ())
318 {
319 tmp++;
320 }
321
322 if (tmp < genericity)
323 {
324 generic = (*i);
325 genericity = tmp;
326 }
327 }
328 return generic;
329}
330
332{
333 NS_LOG_FUNCTION (this);
334 uint16_t port = m_ephemeral;
335 int count = m_portLast - m_portFirst;
336 do
337 {
338 if (count-- < 0)
339 {
340 return 0;
341 }
342 ++port;
343 if (port < m_portFirst || port > m_portLast)
344 {
346 }
347 }
348 while (LookupPortLocal (port));
350 return port;
351}
352
354{
355 return m_endPoints;
356}
357
358} /* namespace ns3 */
359
Describes an IPv6 address.
Definition: ipv6-address.h:50
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
static Ipv6Address GetAllRoutersMulticast()
Get the "all routers multicast" address.
EndPoints Lookup(Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport, Ptr< Ipv6Interface > incomingInterface)
lookup for a match with all the parameters.
bool LookupLocal(Ptr< NetDevice > boundNetDevice, Ipv6Address addr, uint16_t port)
Lookup for address and port.
std::list< Ipv6EndPoint * > EndPoints
Container of the IPv6 endpoints.
EndPoints m_endPoints
A list of IPv6 end points.
uint16_t m_ephemeral
The ephemeral port.
Ipv6EndPoint * Allocate(void)
Allocate a Ipv6EndPoint.
std::list< Ipv6EndPoint * >::iterator EndPointsI
Iterator to the container of the IPv6 endpoints.
EndPoints GetEndPoints() const
Get the entire list of end points registered.
Ipv6EndPoint * SimpleLookup(Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport)
Simple lookup for a four-tuple match.
bool LookupPortLocal(uint16_t port)
Lookup for port local.
uint16_t AllocateEphemeralPort()
Allocate a ephemeral port.
uint16_t m_portFirst
The first ephemeral port.
uint16_t m_portLast
The last ephemeral port.
void DeAllocate(Ipv6EndPoint *endPoint)
Remove a end point.
A representation of an IPv6 endpoint/connection.
Ipv6Address GetLocalAddress()
Get the local address.
void SetPeer(Ipv6Address addr, uint16_t port)
Set the peer information (address and port).
uint16_t GetLocalPort()
Get the local port.
Ptr< NetDevice > GetBoundNetDevice(void)
Returns socket's bound netdevice, if any.
bool IsRxEnabled(void)
Checks if the endpoint can receive packets.
Ipv6Address GetPeerAddress()
Get the peer address.
uint16_t GetPeerPort()
Get the peer port.
virtual Ptr< NetDevice > GetDevice() const
Get the NetDevice.
uint16_t port
Definition: dsdv-manet.cc:45
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#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_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
address
Definition: first.py:44
Every class exported by the ns3 library is enclosed in the ns3 namespace.