A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Groups
Pages
packet-socket.cc
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright (c) 2007 Emmanuelle Laprise, INRIA
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
* Authors: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
19
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
20
*/
21
22
#include "
packet-socket.h
"
23
#include "
packet-socket-address.h
"
24
#include "ns3/log.h"
25
#include "ns3/node.h"
26
#include "ns3/packet.h"
27
#include "ns3/uinteger.h"
28
#include "ns3/trace-source-accessor.h"
29
30
#include <algorithm>
31
32
NS_LOG_COMPONENT_DEFINE
(
"PacketSocket"
);
33
34
namespace
ns3 {
35
36
NS_OBJECT_ENSURE_REGISTERED
(PacketSocket);
37
38
TypeId
39
PacketSocket::GetTypeId
(
void
)
40
{
41
static
TypeId
tid =
TypeId
(
"ns3::PacketSocket"
)
42
.
SetParent
<
Socket
> ()
43
.AddConstructor<PacketSocket> ()
44
.AddTraceSource (
"Drop"
,
"Drop packet due to receive buffer overflow"
,
45
MakeTraceSourceAccessor
(&
PacketSocket::m_dropTrace
))
46
.AddAttribute (
"RcvBufSize"
,
47
"PacketSocket maximum receive buffer size (bytes)"
,
48
UintegerValue
(131072),
49
MakeUintegerAccessor (&
PacketSocket::m_rcvBufSize
),
50
MakeUintegerChecker<uint32_t> ())
51
;
52
return
tid;
53
}
54
55
PacketSocket::PacketSocket
() : m_rxAvailable (0)
56
{
57
NS_LOG_FUNCTION
(
this
);
58
m_state
=
STATE_OPEN
;
59
m_shutdownSend
=
false
;
60
m_shutdownRecv
=
false
;
61
m_errno
=
ERROR_NOTERROR
;
62
m_isSingleDevice
=
false
;
63
m_device
= 0;
64
}
65
66
void
67
PacketSocket::SetNode
(
Ptr<Node>
node)
68
{
69
NS_LOG_FUNCTION
(
this
<< node);
70
m_node
= node;
71
}
72
73
PacketSocket::~PacketSocket
()
74
{
75
NS_LOG_FUNCTION
(
this
);
76
}
77
78
void
79
PacketSocket::DoDispose
(
void
)
80
{
81
NS_LOG_FUNCTION
(
this
);
82
m_device
= 0;
83
}
84
85
enum
Socket::SocketErrno
86
PacketSocket::GetErrno
(
void
)
const
87
{
88
NS_LOG_FUNCTION
(
this
);
89
return
m_errno
;
90
}
91
92
enum
Socket::SocketType
93
PacketSocket::GetSocketType
(
void
)
const
94
{
95
NS_LOG_FUNCTION
(
this
);
96
return
NS3_SOCK_RAW
;
97
}
98
99
Ptr<Node>
100
PacketSocket::GetNode
(
void
)
const
101
{
102
NS_LOG_FUNCTION
(
this
);
103
return
m_node
;
104
}
105
106
int
107
PacketSocket::Bind
(
void
)
108
{
109
NS_LOG_FUNCTION
(
this
);
110
PacketSocketAddress
address
;
111
address.
SetProtocol
(0);
112
address.
SetAllDevices
();
113
return
DoBind
(address);
114
}
115
116
int
117
PacketSocket::Bind6
(
void
)
118
{
119
NS_LOG_FUNCTION
(
this
);
120
return
(
Bind
());
121
}
122
123
int
124
PacketSocket::Bind
(
const
Address
&
address
)
125
{
126
NS_LOG_FUNCTION
(
this
<< address);
127
if
(!
PacketSocketAddress::IsMatchingType
(address))
128
{
129
m_errno
=
ERROR_INVAL
;
130
return
-1;
131
}
132
PacketSocketAddress
ad =
PacketSocketAddress::ConvertFrom
(address);
133
return
DoBind
(ad);
134
}
135
136
int
137
PacketSocket::DoBind
(
const
PacketSocketAddress
&
address
)
138
{
139
NS_LOG_FUNCTION
(
this
<< address);
140
if
(
m_state
==
STATE_BOUND
||
141
m_state
==
STATE_CONNECTED
)
142
{
143
m_errno
=
ERROR_INVAL
;
144
return
-1;
145
}
146
if
(
m_state
==
STATE_CLOSED
)
147
{
148
m_errno
=
ERROR_BADF
;
149
return
-1;
150
}
151
Ptr<NetDevice>
dev;
152
if
(address.
IsSingleDevice
())
153
{
154
dev =
m_node
->
GetDevice
(address.
GetSingleDevice
());
155
}
156
else
157
{
158
dev = 0;
159
}
160
m_node
->
RegisterProtocolHandler
(
MakeCallback
(&
PacketSocket::ForwardUp
,
this
),
161
address.
GetProtocol
(), dev);
162
m_state
=
STATE_BOUND
;
163
m_protocol
= address.
GetProtocol
();
164
m_isSingleDevice
= address.
IsSingleDevice
();
165
m_device
= address.
GetSingleDevice
();
166
m_boundnetdevice
= dev;
167
return
0;
168
}
169
170
int
171
PacketSocket::ShutdownSend
(
void
)
172
{
173
NS_LOG_FUNCTION
(
this
);
174
if
(
m_state
==
STATE_CLOSED
)
175
{
176
m_errno
=
ERROR_BADF
;
177
return
-1;
178
}
179
m_shutdownSend
=
true
;
180
return
0;
181
}
182
183
int
184
PacketSocket::ShutdownRecv
(
void
)
185
{
186
NS_LOG_FUNCTION
(
this
);
187
if
(
m_state
==
STATE_CLOSED
)
188
{
189
m_errno
=
ERROR_BADF
;
190
return
-1;
191
}
192
m_shutdownRecv
=
true
;
193
return
0;
194
}
195
196
int
197
PacketSocket::Close
(
void
)
198
{
199
NS_LOG_FUNCTION
(
this
);
200
if
(
m_state
==
STATE_CLOSED
)
201
{
202
m_errno
=
ERROR_BADF
;
203
return
-1;
204
}
205
else
if
(
m_state
==
STATE_BOUND
||
m_state
==
STATE_CONNECTED
)
206
{
207
m_node
->
UnregisterProtocolHandler
(
MakeCallback
(&
PacketSocket::ForwardUp
,
this
));
208
}
209
m_state
=
STATE_CLOSED
;
210
m_shutdownSend
=
true
;
211
m_shutdownRecv
=
true
;
212
return
0;
213
}
214
215
int
216
PacketSocket::Connect
(
const
Address
&ad)
217
{
218
NS_LOG_FUNCTION
(
this
<< ad);
219
PacketSocketAddress
address
;
220
if
(
m_state
==
STATE_CLOSED
)
221
{
222
m_errno
=
ERROR_BADF
;
223
goto
error;
224
}
225
if
(
m_state
==
STATE_OPEN
)
226
{
227
// connect should happen _after_ bind.
228
m_errno
=
ERROR_INVAL
;
// generic error condition.
229
goto
error;
230
}
231
if
(
m_state
==
STATE_CONNECTED
)
232
{
233
m_errno
=
ERROR_ISCONN
;
234
goto
error;
235
}
236
if
(!
PacketSocketAddress::IsMatchingType
(ad))
237
{
238
m_errno
=
ERROR_AFNOSUPPORT
;
239
goto
error;
240
}
241
m_destAddr
= ad;
242
m_state
=
STATE_CONNECTED
;
243
NotifyConnectionSucceeded
();
244
return
0;
245
error:
246
NotifyConnectionFailed
();
247
return
-1;
248
}
249
int
250
PacketSocket::Listen
(
void
)
251
{
252
NS_LOG_FUNCTION
(
this
);
253
m_errno
=
Socket::ERROR_OPNOTSUPP
;
254
return
-1;
255
}
256
257
int
258
PacketSocket::Send
(
Ptr<Packet>
p, uint32_t flags)
259
{
260
NS_LOG_FUNCTION
(
this
<< p << flags);
261
if
(
m_state
==
STATE_OPEN
||
262
m_state
==
STATE_BOUND
)
263
{
264
m_errno
=
ERROR_NOTCONN
;
265
return
-1;
266
}
267
return
SendTo
(p, flags,
m_destAddr
);
268
}
269
270
uint32_t
271
PacketSocket::GetMinMtu
(
PacketSocketAddress
ad)
const
272
{
273
NS_LOG_FUNCTION
(
this
<< ad);
274
if
(ad.
IsSingleDevice
())
275
{
276
Ptr<NetDevice>
device =
m_node
->
GetDevice
(ad.
GetSingleDevice
());
277
return
device->
GetMtu
();
278
}
279
else
280
{
281
uint32_t minMtu = 0xffff;
282
for
(uint32_t i = 0; i <
m_node
->
GetNDevices
(); i++)
283
{
284
Ptr<NetDevice>
device =
m_node
->
GetDevice
(i);
285
minMtu = std::min (minMtu, (uint32_t)device->
GetMtu
());
286
}
287
return
minMtu;
288
}
289
}
290
291
uint32_t
292
PacketSocket::GetTxAvailable
(
void
)
const
293
{
294
NS_LOG_FUNCTION
(
this
);
295
if
(
m_state
==
STATE_CONNECTED
)
296
{
297
PacketSocketAddress
ad =
PacketSocketAddress::ConvertFrom
(
m_destAddr
);
298
return
GetMinMtu
(ad);
299
}
300
// If we are not connected, we return a 'safe' value by default.
301
return
0xffff;
302
}
303
304
int
305
PacketSocket::SendTo
(
Ptr<Packet>
p, uint32_t flags,
const
Address
&
address
)
306
{
307
NS_LOG_FUNCTION
(
this
<< p << flags << address);
308
PacketSocketAddress
ad;
309
if
(
m_state
==
STATE_CLOSED
)
310
{
311
NS_LOG_LOGIC
(
"ERROR_BADF"
);
312
m_errno
=
ERROR_BADF
;
313
return
-1;
314
}
315
if
(
m_shutdownSend
)
316
{
317
NS_LOG_LOGIC
(
"ERROR_SHUTDOWN"
);
318
m_errno
=
ERROR_SHUTDOWN
;
319
return
-1;
320
}
321
if
(!
PacketSocketAddress::IsMatchingType
(address))
322
{
323
NS_LOG_LOGIC
(
"ERROR_AFNOSUPPORT"
);
324
m_errno
=
ERROR_AFNOSUPPORT
;
325
return
-1;
326
}
327
ad =
PacketSocketAddress::ConvertFrom
(address);
328
if
(p->
GetSize
() >
GetMinMtu
(ad))
329
{
330
m_errno
=
ERROR_MSGSIZE
;
331
return
-1;
332
}
333
334
bool
error =
false
;
335
Address
dest = ad.
GetPhysicalAddress
();
336
if
(ad.
IsSingleDevice
())
337
{
338
Ptr<NetDevice>
device =
m_node
->
GetDevice
(ad.
GetSingleDevice
());
339
if
(!device->
Send
(p, dest, ad.
GetProtocol
()))
340
{
341
NS_LOG_LOGIC
(
"error: NetDevice::Send error"
);
342
error =
true
;
343
}
344
}
345
else
346
{
347
for
(uint32_t i = 0; i <
m_node
->
GetNDevices
(); i++)
348
{
349
Ptr<NetDevice>
device =
m_node
->
GetDevice
(i);
350
if
(!device->
Send
(p, dest, ad.
GetProtocol
()))
351
{
352
NS_LOG_LOGIC
(
"error: NetDevice::Send error"
);
353
error =
true
;
354
}
355
}
356
}
357
if
(!error)
358
{
359
NotifyDataSent
(p->
GetSize
());
360
NotifySend
(
GetTxAvailable
());
361
}
362
363
if
(error)
364
{
365
NS_LOG_LOGIC
(
"ERROR_INVAL 2"
);
366
m_errno
=
ERROR_INVAL
;
367
return
-1;
368
}
369
else
370
{
371
return
p->
GetSize
();
372
}
373
}
374
375
void
376
PacketSocket::ForwardUp
(
Ptr<NetDevice>
device,
Ptr<const Packet>
packet,
377
uint16_t protocol,
const
Address
&from,
378
const
Address
&to,
NetDevice::PacketType
packetType)
379
{
380
NS_LOG_FUNCTION
(
this
<< device << packet << protocol << from << to << packetType);
381
if
(
m_shutdownRecv
)
382
{
383
return
;
384
}
385
PacketSocketAddress
address
;
386
address.
SetPhysicalAddress
(from);
387
address.
SetSingleDevice
(device->
GetIfIndex
());
388
address.
SetProtocol
(protocol);
389
390
if
((
m_rxAvailable
+ packet->
GetSize
()) <=
m_rcvBufSize
)
391
{
392
Ptr<Packet>
copy = packet->
Copy
();
393
DeviceNameTag
dnt;
394
dnt.
SetDeviceName
(device->
GetTypeId
().
GetName
());
395
PacketSocketTag
pst;
396
pst.
SetPacketType
(packetType);
397
pst.
SetDestAddress
(to);
398
SocketAddressTag
tag;
399
tag.
SetAddress
(address);
400
copy->
AddPacketTag
(tag);
// Attach From Physical Address
401
copy->
AddPacketTag
(pst);
// Attach Packet Type and Dest Address
402
copy->
AddPacketTag
(dnt);
// Attach device source name
403
m_deliveryQueue
.push (copy);
404
m_rxAvailable
+= packet->
GetSize
();
405
NS_LOG_LOGIC
(
"UID is "
<< packet->
GetUid
() <<
" PacketSocket "
<<
this
);
406
NotifyDataRecv
();
407
}
408
else
409
{
410
// In general, this case should not occur unless the
411
// receiving application reads data from this socket slowly
412
// in comparison to the arrival rate
413
//
414
// drop and trace packet
415
NS_LOG_WARN
(
"No receive buffer space available. Drop."
);
416
m_dropTrace
(packet);
417
}
418
}
419
420
uint32_t
421
PacketSocket::GetRxAvailable
(
void
)
const
422
{
423
NS_LOG_FUNCTION
(
this
);
424
// We separately maintain this state to avoid walking the queue
425
// every time this might be called
426
return
m_rxAvailable
;
427
}
428
429
Ptr<Packet>
430
PacketSocket::Recv
(uint32_t maxSize, uint32_t flags)
431
{
432
NS_LOG_FUNCTION
(
this
<< maxSize << flags);
433
if
(
m_deliveryQueue
.empty () )
434
{
435
return
0;
436
}
437
Ptr<Packet>
p =
m_deliveryQueue
.front ();
438
if
(p->
GetSize
() <= maxSize)
439
{
440
m_deliveryQueue
.pop ();
441
m_rxAvailable
-= p->
GetSize
();
442
}
443
else
444
{
445
p = 0;
446
}
447
return
p;
448
}
449
450
Ptr<Packet>
451
PacketSocket::RecvFrom
(uint32_t maxSize, uint32_t flags,
Address
&fromAddress)
452
{
453
NS_LOG_FUNCTION
(
this
<< maxSize << flags << fromAddress);
454
Ptr<Packet>
packet =
Recv
(maxSize, flags);
455
if
(packet != 0)
456
{
457
SocketAddressTag
tag;
458
bool
found;
459
found = packet->
PeekPacketTag
(tag);
460
NS_ASSERT
(found);
461
fromAddress = tag.
GetAddress
();
462
}
463
return
packet;
464
}
465
466
int
467
PacketSocket::GetSockName
(
Address
&
address
)
const
468
{
469
NS_LOG_FUNCTION
(
this
<< address);
470
PacketSocketAddress
ad =
PacketSocketAddress::ConvertFrom
(address);
471
472
ad.
SetProtocol
(
m_protocol
);
473
if
(
m_isSingleDevice
)
474
{
475
Ptr<NetDevice>
device =
m_node
->
GetDevice
(ad.
GetSingleDevice
());
476
ad.
SetPhysicalAddress
(device->
GetAddress
());
477
ad.
SetSingleDevice
(
m_device
);
478
}
479
else
480
{
481
ad.
SetPhysicalAddress
(
Address
());
482
ad.
SetAllDevices
();
483
}
484
address = ad;
485
486
return
0;
487
}
488
489
bool
490
PacketSocket::SetAllowBroadcast
(
bool
allowBroadcast)
491
{
492
NS_LOG_FUNCTION
(
this
<< allowBroadcast);
493
if
(allowBroadcast)
494
{
495
return
false
;
496
}
497
return
true
;
498
}
499
500
bool
501
PacketSocket::GetAllowBroadcast
()
const
502
{
503
NS_LOG_FUNCTION
(
this
);
504
return
false
;
505
}
506
507
/***************************************************************
508
* PacketSocket Tags
509
***************************************************************/
510
511
PacketSocketTag::PacketSocketTag
()
512
{
513
}
514
515
void
516
PacketSocketTag::SetPacketType
(
NetDevice::PacketType
t)
517
{
518
m_packetType
= t;
519
}
520
521
NetDevice::PacketType
522
PacketSocketTag::GetPacketType
(
void
)
const
523
{
524
return
m_packetType
;
525
}
526
527
void
528
PacketSocketTag::SetDestAddress
(
Address
a)
529
{
530
m_destAddr
= a;
531
}
532
533
Address
534
PacketSocketTag::GetDestAddress
(
void
)
const
535
{
536
return
m_destAddr
;
537
}
538
539
NS_OBJECT_ENSURE_REGISTERED
(
PacketSocketTag
);
540
541
TypeId
542
PacketSocketTag::GetTypeId
(
void
)
543
{
544
static
TypeId
tid =
TypeId
(
"ns3::PacketSocketTag"
)
545
.
SetParent
<
Tag
> ()
546
.AddConstructor<PacketSocketTag> ()
547
;
548
return
tid;
549
}
550
TypeId
551
PacketSocketTag::GetInstanceTypeId
(
void
)
const
552
{
553
return
GetTypeId
();
554
}
555
uint32_t
556
PacketSocketTag::GetSerializedSize
(
void
)
const
557
{
558
return
1 +
m_destAddr
.
GetSerializedSize
();
559
}
560
void
561
PacketSocketTag::Serialize
(
TagBuffer
i)
const
562
{
563
i.
WriteU8
(
m_packetType
);
564
m_destAddr
.
Serialize
(i);
565
}
566
void
567
PacketSocketTag::Deserialize
(
TagBuffer
i)
568
{
569
m_packetType
= (
NetDevice::PacketType
) i.
ReadU8
();
570
m_destAddr
.
Deserialize
(i);
571
}
572
void
573
PacketSocketTag::Print
(std::ostream &os)
const
574
{
575
os <<
"packetType="
<<
m_packetType
;
576
}
577
578
/***************************************************************
579
* DeviceName Tags
580
***************************************************************/
581
582
DeviceNameTag::DeviceNameTag
()
583
{
584
}
585
586
void
587
DeviceNameTag::SetDeviceName
(std::string n)
588
{
589
if
( n.substr(0,5) ==
"ns3::"
)
590
{
591
n = n.substr (5);
592
}
593
m_deviceName
= n;
594
}
595
596
std::string
597
DeviceNameTag::GetDeviceName
(
void
)
const
598
{
599
return
m_deviceName
;
600
}
601
602
NS_OBJECT_ENSURE_REGISTERED
(
DeviceNameTag
);
603
604
TypeId
605
DeviceNameTag::GetTypeId
(
void
)
606
{
607
static
TypeId
tid =
TypeId
(
"ns3::DeviceNameTag"
)
608
.
SetParent
<
Tag
> ()
609
.AddConstructor<DeviceNameTag> ();
610
return
tid;
611
}
612
TypeId
613
DeviceNameTag::GetInstanceTypeId
(
void
)
const
614
{
615
return
GetTypeId
();
616
}
617
uint32_t
618
DeviceNameTag::GetSerializedSize
(
void
)
const
619
{
620
uint32_t
s
= 1 +
m_deviceName
.size();
// +1 for name length field
621
s = std::min (s, (uint32_t)
PacketTagList::TagData::MAX_SIZE
);
622
return
s
;
623
}
624
void
625
DeviceNameTag::Serialize
(
TagBuffer
i)
const
626
{
627
const
char
*n =
m_deviceName
.c_str();
628
uint8_t l = (uint8_t)
m_deviceName
.size ();
629
630
l = std::min ((uint32_t)l, (uint32_t)
PacketTagList::TagData::MAX_SIZE
- 1);
631
632
i.
WriteU8
(l);
633
i.
Write
( (uint8_t*) n , (uint32_t) l);
634
}
635
void
636
DeviceNameTag::Deserialize
(
TagBuffer
i)
637
{
638
uint8_t l = i.
ReadU8
();
639
char
buf[256];
640
641
i.
Read
( (uint8_t* ) buf, (uint32_t) l);
642
m_deviceName
= std::string (buf, l);
643
}
644
void
645
DeviceNameTag::Print
(std::ostream &os)
const
646
{
647
os <<
"DeviceName="
<<
m_deviceName
;
648
}
649
650
651
}
// namespace ns3
src
network
utils
packet-socket.cc
Generated on Fri Aug 30 2013 01:43:00 for ns-3 by
1.8.1.2