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
point-to-point-net-device.cc
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright (c) 2007, 2008 University of Washington
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
19
#include "ns3/log.h"
20
#include "ns3/queue.h"
21
#include "ns3/simulator.h"
22
#include "ns3/mac48-address.h"
23
#include "ns3/llc-snap-header.h"
24
#include "ns3/error-model.h"
25
#include "ns3/trace-source-accessor.h"
26
#include "ns3/uinteger.h"
27
#include "ns3/pointer.h"
28
#include "ns3/mpi-interface.h"
29
#include "
point-to-point-net-device.h
"
30
#include "
point-to-point-channel.h
"
31
#include "
ppp-header.h
"
32
33
NS_LOG_COMPONENT_DEFINE
(
"PointToPointNetDevice"
);
34
35
namespace
ns3 {
36
37
NS_OBJECT_ENSURE_REGISTERED
(PointToPointNetDevice);
38
39
TypeId
40
PointToPointNetDevice::GetTypeId
(
void
)
41
{
42
static
TypeId
tid =
TypeId
(
"ns3::PointToPointNetDevice"
)
43
.
SetParent
<
NetDevice
> ()
44
.AddConstructor<PointToPointNetDevice> ()
45
.AddAttribute (
"Mtu"
,
"The MAC-level Maximum Transmission Unit"
,
46
UintegerValue
(
DEFAULT_MTU
),
47
MakeUintegerAccessor (&
PointToPointNetDevice::SetMtu
,
48
&
PointToPointNetDevice::GetMtu
),
49
MakeUintegerChecker<uint16_t> ())
50
.AddAttribute (
"Address"
,
51
"The MAC address of this device."
,
52
Mac48AddressValue
(
Mac48Address
(
"ff:ff:ff:ff:ff:ff"
)),
53
MakeMac48AddressAccessor (&
PointToPointNetDevice::m_address
),
54
MakeMac48AddressChecker ())
55
.AddAttribute (
"DataRate"
,
56
"The default data rate for point to point links"
,
57
DataRateValue
(
DataRate
(
"32768b/s"
)),
58
MakeDataRateAccessor (&
PointToPointNetDevice::m_bps
),
59
MakeDataRateChecker ())
60
.AddAttribute (
"ReceiveErrorModel"
,
61
"The receiver error model used to simulate packet loss"
,
62
PointerValue
(),
63
MakePointerAccessor (&
PointToPointNetDevice::m_receiveErrorModel
),
64
MakePointerChecker<ErrorModel> ())
65
.AddAttribute (
"InterframeGap"
,
66
"The time to wait between packet (frame) transmissions"
,
67
TimeValue
(
Seconds
(0.0)),
68
MakeTimeAccessor (&
PointToPointNetDevice::m_tInterframeGap
),
69
MakeTimeChecker ())
70
71
//
72
// Transmit queueing discipline for the device which includes its own set
73
// of trace hooks.
74
//
75
.AddAttribute (
"TxQueue"
,
76
"A queue to use as the transmit queue in the device."
,
77
PointerValue
(),
78
MakePointerAccessor (&
PointToPointNetDevice::m_queue
),
79
MakePointerChecker<Queue> ())
80
81
//
82
// Trace sources at the "top" of the net device, where packets transition
83
// to/from higher layers.
84
//
85
.AddTraceSource (
"MacTx"
,
86
"Trace source indicating a packet has arrived for transmission by this device"
,
87
MakeTraceSourceAccessor
(&
PointToPointNetDevice::m_macTxTrace
))
88
.AddTraceSource (
"MacTxDrop"
,
89
"Trace source indicating a packet has been dropped by the device before transmission"
,
90
MakeTraceSourceAccessor
(&
PointToPointNetDevice::m_macTxDropTrace
))
91
.AddTraceSource (
"MacPromiscRx"
,
92
"A packet has been received by this device, has been passed up from the physical layer "
93
"and is being forwarded up the local protocol stack. This is a promiscuous trace,"
,
94
MakeTraceSourceAccessor
(&
PointToPointNetDevice::m_macPromiscRxTrace
))
95
.AddTraceSource (
"MacRx"
,
96
"A packet has been received by this device, has been passed up from the physical layer "
97
"and is being forwarded up the local protocol stack. This is a non-promiscuous trace,"
,
98
MakeTraceSourceAccessor
(&
PointToPointNetDevice::m_macRxTrace
))
99
#if 0
100
// Not currently implemented for this device
101
.AddTraceSource (
"MacRxDrop"
,
102
"Trace source indicating a packet was dropped before being forwarded up the stack"
,
103
MakeTraceSourceAccessor
(&
PointToPointNetDevice::m_macRxDropTrace
))
104
#endif
105
//
106
// Trace souces at the "bottom" of the net device, where packets transition
107
// to/from the channel.
108
//
109
.AddTraceSource (
"PhyTxBegin"
,
110
"Trace source indicating a packet has begun transmitting over the channel"
,
111
MakeTraceSourceAccessor
(&
PointToPointNetDevice::m_phyTxBeginTrace
))
112
.AddTraceSource (
"PhyTxEnd"
,
113
"Trace source indicating a packet has been completely transmitted over the channel"
,
114
MakeTraceSourceAccessor
(&
PointToPointNetDevice::m_phyTxEndTrace
))
115
.AddTraceSource (
"PhyTxDrop"
,
116
"Trace source indicating a packet has been dropped by the device during transmission"
,
117
MakeTraceSourceAccessor
(&
PointToPointNetDevice::m_phyTxDropTrace
))
118
#if 0
119
// Not currently implemented for this device
120
.AddTraceSource (
"PhyRxBegin"
,
121
"Trace source indicating a packet has begun being received by the device"
,
122
MakeTraceSourceAccessor
(&
PointToPointNetDevice::m_phyRxBeginTrace
))
123
#endif
124
.AddTraceSource (
"PhyRxEnd"
,
125
"Trace source indicating a packet has been completely received by the device"
,
126
MakeTraceSourceAccessor
(&
PointToPointNetDevice::m_phyRxEndTrace
))
127
.AddTraceSource (
"PhyRxDrop"
,
128
"Trace source indicating a packet has been dropped by the device during reception"
,
129
MakeTraceSourceAccessor
(&
PointToPointNetDevice::m_phyRxDropTrace
))
130
131
//
132
// Trace sources designed to simulate a packet sniffer facility (tcpdump).
133
// Note that there is really no difference between promiscuous and
134
// non-promiscuous traces in a point-to-point link.
135
//
136
.AddTraceSource (
"Sniffer"
,
137
"Trace source simulating a non-promiscuous packet sniffer attached to the device"
,
138
MakeTraceSourceAccessor
(&
PointToPointNetDevice::m_snifferTrace
))
139
.AddTraceSource (
"PromiscSniffer"
,
140
"Trace source simulating a promiscuous packet sniffer attached to the device"
,
141
MakeTraceSourceAccessor
(&
PointToPointNetDevice::m_promiscSnifferTrace
))
142
;
143
return
tid;
144
}
145
146
147
PointToPointNetDevice::PointToPointNetDevice
()
148
:
149
m_txMachineState (READY),
150
m_channel (0),
151
m_linkUp (false),
152
m_currentPkt (0)
153
{
154
NS_LOG_FUNCTION
(
this
);
155
}
156
157
PointToPointNetDevice::~PointToPointNetDevice
()
158
{
159
NS_LOG_FUNCTION_NOARGS
();
160
}
161
162
void
163
PointToPointNetDevice::AddHeader
(
Ptr<Packet>
p, uint16_t protocolNumber)
164
{
165
NS_LOG_FUNCTION_NOARGS
();
166
PppHeader
ppp;
167
ppp.
SetProtocol
(
EtherToPpp
(protocolNumber));
168
p->
AddHeader
(ppp);
169
}
170
171
bool
172
PointToPointNetDevice::ProcessHeader
(
Ptr<Packet>
p, uint16_t& param)
173
{
174
NS_LOG_FUNCTION_NOARGS
();
175
PppHeader
ppp;
176
p->
RemoveHeader
(ppp);
177
param =
PppToEther
(ppp.
GetProtocol
());
178
return
true
;
179
}
180
181
void
182
PointToPointNetDevice::DoDispose
()
183
{
184
NS_LOG_FUNCTION_NOARGS
();
185
m_node
= 0;
186
m_channel
= 0;
187
m_receiveErrorModel
= 0;
188
m_currentPkt
= 0;
189
NetDevice::DoDispose
();
190
}
191
192
void
193
PointToPointNetDevice::SetDataRate
(
DataRate
bps)
194
{
195
NS_LOG_FUNCTION_NOARGS
();
196
m_bps
= bps;
197
}
198
199
void
200
PointToPointNetDevice::SetInterframeGap
(
Time
t)
201
{
202
NS_LOG_FUNCTION_NOARGS
();
203
m_tInterframeGap
= t;
204
}
205
206
bool
207
PointToPointNetDevice::TransmitStart
(
Ptr<Packet>
p)
208
{
209
NS_LOG_FUNCTION
(
this
<< p);
210
NS_LOG_LOGIC
(
"UID is "
<< p->
GetUid
() <<
")"
);
211
212
//
213
// This function is called to start the process of transmitting a packet.
214
// We need to tell the channel that we've started wiggling the wire and
215
// schedule an event that will be executed when the transmission is complete.
216
//
217
NS_ASSERT_MSG
(
m_txMachineState
==
READY
,
"Must be READY to transmit"
);
218
m_txMachineState
=
BUSY
;
219
m_currentPkt
= p;
220
m_phyTxBeginTrace
(
m_currentPkt
);
221
222
Time
txTime =
Seconds
(
m_bps
.
CalculateTxTime
(p->
GetSize
()));
223
Time
txCompleteTime = txTime +
m_tInterframeGap
;
224
225
NS_LOG_LOGIC
(
"Schedule TransmitCompleteEvent in "
<< txCompleteTime.
GetSeconds
() <<
"sec"
);
226
Simulator::Schedule
(txCompleteTime, &
PointToPointNetDevice::TransmitComplete
,
this
);
227
228
bool
result =
m_channel
->
TransmitStart
(p,
this
, txTime);
229
if
(result ==
false
)
230
{
231
m_phyTxDropTrace
(p);
232
}
233
return
result;
234
}
235
236
void
237
PointToPointNetDevice::TransmitComplete
(
void
)
238
{
239
NS_LOG_FUNCTION_NOARGS
();
240
241
//
242
// This function is called to when we're all done transmitting a packet.
243
// We try and pull another packet off of the transmit queue. If the queue
244
// is empty, we are done, otherwise we need to start transmitting the
245
// next packet.
246
//
247
NS_ASSERT_MSG
(
m_txMachineState
==
BUSY
,
"Must be BUSY if transmitting"
);
248
m_txMachineState
=
READY
;
249
250
NS_ASSERT_MSG
(
m_currentPkt
!= 0,
"PointToPointNetDevice::TransmitComplete(): m_currentPkt zero"
);
251
252
m_phyTxEndTrace
(
m_currentPkt
);
253
m_currentPkt
= 0;
254
255
Ptr<Packet>
p =
m_queue
->
Dequeue
();
256
if
(p == 0)
257
{
258
//
259
// No packet was on the queue, so we just exit.
260
//
261
return
;
262
}
263
264
//
265
// Got another packet off of the queue, so start the transmit process agin.
266
//
267
m_snifferTrace
(p);
268
m_promiscSnifferTrace
(p);
269
TransmitStart
(p);
270
}
271
272
bool
273
PointToPointNetDevice::Attach
(
Ptr<PointToPointChannel>
ch)
274
{
275
NS_LOG_FUNCTION
(
this
<< &ch);
276
277
m_channel
= ch;
278
279
m_channel
->
Attach
(
this
);
280
281
//
282
// This device is up whenever it is attached to a channel. A better plan
283
// would be to have the link come up when both devices are attached, but this
284
// is not done for now.
285
//
286
NotifyLinkUp
();
287
return
true
;
288
}
289
290
void
291
PointToPointNetDevice::SetQueue
(
Ptr<Queue>
q)
292
{
293
NS_LOG_FUNCTION
(
this
<< q);
294
m_queue
= q;
295
}
296
297
void
298
PointToPointNetDevice::SetReceiveErrorModel
(
Ptr<ErrorModel>
em)
299
{
300
NS_LOG_FUNCTION
(
this
<< em);
301
m_receiveErrorModel
= em;
302
}
303
304
void
305
PointToPointNetDevice::Receive
(
Ptr<Packet>
packet)
306
{
307
NS_LOG_FUNCTION
(
this
<< packet);
308
uint16_t protocol = 0;
309
310
if
(
m_receiveErrorModel
&&
m_receiveErrorModel
->
IsCorrupt
(packet) )
311
{
312
//
313
// If we have an error model and it indicates that it is time to lose a
314
// corrupted packet, don't forward this packet up, let it go.
315
//
316
m_phyRxDropTrace
(packet);
317
}
318
else
319
{
320
//
321
// Hit the trace hooks. All of these hooks are in the same place in this
322
// device becuase it is so simple, but this is not usually the case in
323
// more complicated devices.
324
//
325
m_snifferTrace
(packet);
326
m_promiscSnifferTrace
(packet);
327
m_phyRxEndTrace
(packet);
328
329
//
330
// Strip off the point-to-point protocol header and forward this packet
331
// up the protocol stack. Since this is a simple point-to-point link,
332
// there is no difference in what the promisc callback sees and what the
333
// normal receive callback sees.
334
//
335
ProcessHeader
(packet, protocol);
336
337
if
(!
m_promiscCallback
.
IsNull
())
338
{
339
m_macPromiscRxTrace
(packet);
340
m_promiscCallback
(
this
, packet, protocol,
GetRemote
(),
GetAddress
(),
NetDevice::PACKET_HOST
);
341
}
342
343
m_macRxTrace
(packet);
344
m_rxCallback
(
this
, packet, protocol,
GetRemote
());
345
}
346
}
347
348
Ptr<Queue>
349
PointToPointNetDevice::GetQueue
(
void
)
const
350
{
351
NS_LOG_FUNCTION_NOARGS
();
352
return
m_queue
;
353
}
354
355
void
356
PointToPointNetDevice::NotifyLinkUp
(
void
)
357
{
358
m_linkUp
=
true
;
359
m_linkChangeCallbacks
();
360
}
361
362
void
363
PointToPointNetDevice::SetIfIndex
(
const
uint32_t index)
364
{
365
m_ifIndex
= index;
366
}
367
368
uint32_t
369
PointToPointNetDevice::GetIfIndex
(
void
)
const
370
{
371
return
m_ifIndex
;
372
}
373
374
Ptr<Channel>
375
PointToPointNetDevice::GetChannel
(
void
)
const
376
{
377
return
m_channel
;
378
}
379
380
//
381
// This is a point-to-point device, so we really don't need any kind of address
382
// information. However, the base class NetDevice wants us to define the
383
// methods to get and set the address. Rather than be rude and assert, we let
384
// clients get and set the address, but simply ignore them.
385
386
void
387
PointToPointNetDevice::SetAddress
(
Address
address)
388
{
389
m_address
=
Mac48Address::ConvertFrom
(address);
390
}
391
392
Address
393
PointToPointNetDevice::GetAddress
(
void
)
const
394
{
395
return
m_address
;
396
}
397
398
bool
399
PointToPointNetDevice::IsLinkUp
(
void
)
const
400
{
401
return
m_linkUp
;
402
}
403
404
void
405
PointToPointNetDevice::AddLinkChangeCallback
(
Callback<void>
callback)
406
{
407
m_linkChangeCallbacks
.
ConnectWithoutContext
(callback);
408
}
409
410
//
411
// This is a point-to-point device, so every transmission is a broadcast to
412
// all of the devices on the network.
413
//
414
bool
415
PointToPointNetDevice::IsBroadcast
(
void
)
const
416
{
417
return
true
;
418
}
419
420
//
421
// We don't really need any addressing information since this is a
422
// point-to-point device. The base class NetDevice wants us to return a
423
// broadcast address, so we make up something reasonable.
424
//
425
Address
426
PointToPointNetDevice::GetBroadcast
(
void
)
const
427
{
428
return
Mac48Address
(
"ff:ff:ff:ff:ff:ff"
);
429
}
430
431
bool
432
PointToPointNetDevice::IsMulticast
(
void
)
const
433
{
434
return
true
;
435
}
436
437
Address
438
PointToPointNetDevice::GetMulticast
(
Ipv4Address
multicastGroup)
const
439
{
440
return
Mac48Address
(
"01:00:5e:00:00:00"
);
441
}
442
443
Address
444
PointToPointNetDevice::GetMulticast
(
Ipv6Address
addr)
const
445
{
446
NS_LOG_FUNCTION
(
this
<< addr);
447
return
Mac48Address
(
"33:33:00:00:00:00"
);
448
}
449
450
bool
451
PointToPointNetDevice::IsPointToPoint
(
void
)
const
452
{
453
return
true
;
454
}
455
456
bool
457
PointToPointNetDevice::IsBridge
(
void
)
const
458
{
459
return
false
;
460
}
461
462
bool
463
PointToPointNetDevice::Send
(
464
Ptr<Packet>
packet,
465
const
Address
&dest,
466
uint16_t protocolNumber)
467
{
468
NS_LOG_FUNCTION_NOARGS
();
469
NS_LOG_LOGIC
(
"p="
<< packet <<
", dest="
<< &dest);
470
NS_LOG_LOGIC
(
"UID is "
<< packet->
GetUid
());
471
472
//
473
// If IsLinkUp() is false it means there is no channel to send any packet
474
// over so we just hit the drop trace on the packet and return an error.
475
//
476
if
(
IsLinkUp
() ==
false
)
477
{
478
m_macTxDropTrace
(packet);
479
return
false
;
480
}
481
482
//
483
// Stick a point to point protocol header on the packet in preparation for
484
// shoving it out the door.
485
//
486
AddHeader
(packet, protocolNumber);
487
488
m_macTxTrace
(packet);
489
490
//
491
// If there's a transmission in progress, we enque the packet for later
492
// transmission; otherwise we send it now.
493
//
494
if
(
m_txMachineState
==
READY
)
495
{
496
//
497
// Even if the transmitter is immediately available, we still enqueue and
498
// dequeue the packet to hit the tracing hooks.
499
//
500
if
(
m_queue
->
Enqueue
(packet) ==
true
)
501
{
502
packet =
m_queue
->
Dequeue
();
503
m_snifferTrace
(packet);
504
m_promiscSnifferTrace
(packet);
505
return
TransmitStart
(packet);
506
}
507
else
508
{
509
// Enqueue may fail (overflow)
510
m_macTxDropTrace
(packet);
511
return
false
;
512
}
513
}
514
else
515
{
516
return
m_queue
->
Enqueue
(packet);
517
}
518
}
519
520
bool
521
PointToPointNetDevice::SendFrom
(
Ptr<Packet>
packet,
522
const
Address
&source,
523
const
Address
&dest,
524
uint16_t protocolNumber)
525
{
526
return
false
;
527
}
528
529
Ptr<Node>
530
PointToPointNetDevice::GetNode
(
void
)
const
531
{
532
return
m_node
;
533
}
534
535
void
536
PointToPointNetDevice::SetNode
(
Ptr<Node>
node)
537
{
538
m_node
= node;
539
}
540
541
bool
542
PointToPointNetDevice::NeedsArp
(
void
)
const
543
{
544
return
false
;
545
}
546
547
void
548
PointToPointNetDevice::SetReceiveCallback
(
NetDevice::ReceiveCallback
cb)
549
{
550
m_rxCallback
= cb;
551
}
552
553
void
554
PointToPointNetDevice::SetPromiscReceiveCallback
(
NetDevice::PromiscReceiveCallback
cb)
555
{
556
m_promiscCallback
= cb;
557
}
558
559
bool
560
PointToPointNetDevice::SupportsSendFrom
(
void
)
const
561
{
562
return
false
;
563
}
564
565
void
566
PointToPointNetDevice::DoMpiReceive
(
Ptr<Packet>
p)
567
{
568
Receive
(p);
569
}
570
571
Address
572
PointToPointNetDevice::GetRemote
(
void
)
const
573
{
574
NS_ASSERT
(
m_channel
->
GetNDevices
() == 2);
575
for
(uint32_t i = 0; i <
m_channel
->
GetNDevices
(); ++i)
576
{
577
Ptr<NetDevice>
tmp =
m_channel
->
GetDevice
(i);
578
if
(tmp !=
this
)
579
{
580
return
tmp->
GetAddress
();
581
}
582
}
583
NS_ASSERT
(
false
);
584
// quiet compiler.
585
return
Address
();
586
}
587
588
bool
589
PointToPointNetDevice::SetMtu
(uint16_t mtu)
590
{
591
NS_LOG_FUNCTION
(
this
<< mtu);
592
m_mtu
= mtu;
593
return
true
;
594
}
595
596
uint16_t
597
PointToPointNetDevice::GetMtu
(
void
)
const
598
{
599
NS_LOG_FUNCTION_NOARGS
();
600
return
m_mtu
;
601
}
602
603
uint16_t
604
PointToPointNetDevice::PppToEther
(uint16_t proto)
605
{
606
switch
(proto)
607
{
608
case
0x0021:
return
0x0800;
//IPv4
609
case
0x0057:
return
0x86DD;
//IPv6
610
default
:
NS_ASSERT_MSG
(
false
,
"PPP Protocol number not defined!"
);
611
}
612
return
0;
613
}
614
615
uint16_t
616
PointToPointNetDevice::EtherToPpp
(uint16_t proto)
617
{
618
switch
(proto)
619
{
620
case
0x0800:
return
0x0021;
//IPv4
621
case
0x86DD:
return
0x0057;
//IPv6
622
default
:
NS_ASSERT_MSG
(
false
,
"PPP Protocol number not defined!"
);
623
}
624
return
0;
625
}
626
627
628
}
// namespace ns3
src
point-to-point
model
point-to-point-net-device.cc
Generated on Tue Oct 9 2012 16:45:45 for ns-3 by
1.8.1.2