branch merge
@@ -2,13 +2,21 @@ TEXI2HTML = texi2html
|
||||
TEXI2PDF = texi2dvi --pdf
|
||||
EPSTOPDF = epstopdf
|
||||
TGIF = tgif
|
||||
DIA = dia
|
||||
CONVERT = convert
|
||||
CSS = --css-include=tutorial.css
|
||||
SPLIT = --split section
|
||||
|
||||
TGIF_SOURCES = helpers.obj
|
||||
DIA_SOURCES = buffer.dia pp.dia dumbbell.dia star.dia
|
||||
TGIF_SOURCES = packet.obj helpers.obj
|
||||
|
||||
DIA_EPS = ${DIA_SOURCES:.dia=.eps}
|
||||
DIA_PNG = ${DIA_SOURCES:.dia=.png}
|
||||
DIA_PDF = ${DIA_SOURCES:.dia=.pdf}
|
||||
|
||||
TGIF_EPS = ${TGIF_SOURCES:.obj=.eps}
|
||||
TGIF_PNG = ${TGIF_SOURCES:.obj=.eps}
|
||||
TGIF_PNG = ${TGIF_SOURCES:.obj=.png}
|
||||
TGIF_PDF = ${TGIF_SOURCES:.obj=.pdf}
|
||||
|
||||
all: images html split-html pdf
|
||||
|
||||
@@ -17,8 +25,11 @@ all: images html split-html pdf
|
||||
# buffer may be needed (xorg-x11-server-Xvfb) to provide a "fake"
|
||||
# display
|
||||
images:
|
||||
cd figures/; $(TGIF) -print -eps $(TGIF_SOURCES)
|
||||
cd figures/; $(DIA) -t png $(DIA_SOURCES)
|
||||
cd figures/; $(DIA) -t eps $(DIA_SOURCES)
|
||||
cd figures/; $(foreach FILE,$(DIA_EPS),$(EPSTOPDF) $(FILE);)
|
||||
cd figures/; $(TGIF) -print -png $(TGIF_SOURCES)
|
||||
cd figures/; $(TGIF) -print -eps $(TGIF_SOURCES)
|
||||
cd figures/; $(foreach FILE,$(TGIF_EPS),$(EPSTOPDF) $(FILE);)
|
||||
|
||||
html: images
|
||||
@@ -30,5 +41,9 @@ split-html: images
|
||||
pdf: images
|
||||
$(TEXI2PDF) tutorial.texi
|
||||
|
||||
clean:
|
||||
figures-clean:
|
||||
cd figures/; rm -rf $(DIA_EPS); rm -rf $(DIA_PNG); rm -rf $(DIA_PDF)
|
||||
cd figures/; rm -rf $(TGIF_EPS); rm -rf $(TGIF_PNG); rm -rf $(TGIF_PDF)
|
||||
|
||||
clean: figures-clean
|
||||
rm -rf tutorial.aux tutorial.cp tutorial.cps tutorial.fn tutorial.ky tutorial.pg tutorial.tp tutorial.vr tutorial.toc tutorial.log tutorial.pdf tutorial.html tutorial/
|
||||
|
||||
|
Before Width: | Height: | Size: 8.0 KiB |
@@ -1,8 +1,17 @@
|
||||
Please write image files in a vector graphics format, when possible, and
|
||||
generate the .png and .pdf versions on the fly (see ../Makefile).
|
||||
|
||||
Recommended tools are dia, tgif, and xfig. Store the .dia, .obj, or .fig
|
||||
versions in mercurial, but not the .png or .pdfs.
|
||||
Currently supported tools are dia and tgif. xfig could be added similarly
|
||||
if someone wants to add it. The main requirement for adding another format
|
||||
is that the tool to edit it is freely available and that a cron script can
|
||||
autogenerate the pdf and png from the figure source.
|
||||
|
||||
Store the .dia, or .obj versions in mercurial, but not the .png or .pdfs.
|
||||
If the figure is not available in a vector graphics format, store both
|
||||
a .png and a .pdf version in this directory.
|
||||
|
||||
If you add a source (.dia, .obj) file here, remember to add it to
|
||||
the list of figure sources in the Makefile in the directory above
|
||||
|
||||
Note: tgif can convert from .obj to .pdf, but the pdf that results takes
|
||||
up a whole page. Instead, we convert to an intermediate .eps step, and
|
||||
|
||||
1623
doc/tutorial/figures/buffer.dia
Normal file
BIN
doc/tutorial/figures/dumbbell.dia
Normal file
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.0 KiB |
227
doc/tutorial/figures/packet.obj
Normal file
@@ -0,0 +1,227 @@
|
||||
%TGIF 4.1.43-QPL
|
||||
state(0,37,100.000,0,64,0,32,0,9,1,1,1,0,0,0,1,0,'Courier-Bold',1,103680,0,3,0,10,0,0,1,1,0,16,0,0,1,1,1,1,1088,1408,1,0,2880,0).
|
||||
%
|
||||
% @(#)$Header$
|
||||
% %W%
|
||||
%
|
||||
unit("1 pixel/pixel").
|
||||
color_info(11,65535,0,[
|
||||
"magenta", 65535, 0, 65535, 65535, 0, 65535, 1,
|
||||
"red", 65535, 0, 0, 65535, 0, 0, 1,
|
||||
"green", 0, 65535, 0, 0, 65535, 0, 1,
|
||||
"blue", 0, 0, 65535, 0, 0, 65535, 1,
|
||||
"yellow", 65535, 65535, 0, 65535, 65535, 0, 1,
|
||||
"pink", 65535, 49344, 52171, 65535, 49344, 52171, 1,
|
||||
"cyan", 0, 65535, 65535, 0, 65535, 65535, 1,
|
||||
"CadetBlue", 24415, 40606, 41120, 24415, 40606, 41120, 1,
|
||||
"white", 65535, 65535, 65535, 65535, 65535, 65535, 1,
|
||||
"black", 0, 0, 0, 0, 0, 0, 1,
|
||||
"DarkSlateGray", 12079, 20303, 20303, 12079, 20303, 20303, 1
|
||||
]).
|
||||
script_frac("0.6").
|
||||
fg_bg_colors('black','white').
|
||||
dont_reencode("FFDingbests:ZapfDingbats").
|
||||
page(1,"",1,'').
|
||||
box('black','',32,48,240,256,0,3,1,0,0,0,0,0,0,'3',0,[
|
||||
]).
|
||||
text('black',64,10,1,0,1,121,28,3,22,6,0,0,0,0,2,121,28,0,0,"",0,0,0,0,32,'',[
|
||||
minilines(121,28,0,0,0,0,0,[
|
||||
mini_line(121,22,6,0,0,0,[
|
||||
str_block(0,121,22,6,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,138240,121,22,6,0,0,0,0,0,0,0,
|
||||
"class Packet")])
|
||||
])
|
||||
])]).
|
||||
text('black',416,100,1,0,1,116,28,15,22,6,0,0,0,0,2,116,28,0,0,"",0,0,0,0,122,'',[
|
||||
minilines(116,28,0,0,0,0,0,[
|
||||
mini_line(116,22,6,0,0,0,[
|
||||
str_block(0,116,22,6,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,138240,116,22,6,0,0,0,0,0,0,0,
|
||||
"class Buffer")])
|
||||
])
|
||||
])]).
|
||||
text('black',48,178,4,0,1,83,69,32,14,4,0,0,0,0,2,83,69,0,0,"",0,0,0,0,192,'',[
|
||||
minilines(83,69,0,0,0,0,0,[
|
||||
mini_line(80,14,4,0,0,0,[
|
||||
str_block(0,80,14,4,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Bold',1,80640,80,14,4,0,-1,0,0,0,0,0,
|
||||
"private data:")])
|
||||
]),
|
||||
mini_line(59,14,3,0,0,0,[
|
||||
str_block(0,59,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,59,14,3,0,0,0,0,0,0,0,
|
||||
"- unique id")])
|
||||
]),
|
||||
mini_line(83,14,3,0,0,0,[
|
||||
str_block(0,83,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,83,14,3,0,0,0,0,0,0,0,
|
||||
"- Buffer object")])
|
||||
]),
|
||||
mini_line(76,14,3,0,0,0,[
|
||||
str_block(0,76,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,76,14,3,0,0,0,0,0,0,0,
|
||||
"- Tags object")])
|
||||
])
|
||||
])]).
|
||||
text('black',112,288,1,0,1,103,28,82,22,6,0,0,0,0,2,103,28,0,0,"",0,0,0,0,310,'',[
|
||||
minilines(103,28,0,0,0,0,0,[
|
||||
mini_line(103,22,6,0,0,0,[
|
||||
str_block(0,103,22,6,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,138240,103,22,6,0,-1,0,0,0,0,0,
|
||||
"class Tags")])
|
||||
])
|
||||
])]).
|
||||
text('black',48,50,5,0,1,175,86,176,14,4,0,0,0,0,2,175,86,0,0,"",0,0,0,0,64,'',[
|
||||
minilines(175,86,0,0,0,0,0,[
|
||||
mini_line(105,14,4,0,0,0,[
|
||||
str_block(0,105,14,4,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Bold',1,80640,105,14,4,0,-1,0,0,0,0,0,
|
||||
"public functions:")])
|
||||
]),
|
||||
mini_line(80,14,3,0,0,0,[
|
||||
str_block(0,80,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,80,14,3,0,-1,0,0,0,0,0,
|
||||
"- constructors")])
|
||||
]),
|
||||
mini_line(175,14,3,0,0,0,[
|
||||
str_block(0,175,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,175,14,3,0,-1,0,0,0,0,0,
|
||||
"- add/remove/peek at Headers")])
|
||||
]),
|
||||
mini_line(155,14,3,0,0,0,[
|
||||
str_block(0,155,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,155,14,3,0,-1,0,0,0,0,0,
|
||||
"- add/remove/peek at Tags")])
|
||||
]),
|
||||
mini_line(88,14,3,0,0,0,[
|
||||
str_block(0,88,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,88,14,3,0,0,0,0,0,0,0,
|
||||
"- fragmentation")])
|
||||
])
|
||||
])]).
|
||||
box('black','',384,144,614,352,0,3,1,245,0,0,0,0,0,'3',0,[
|
||||
]).
|
||||
text('black',400,274,4,0,1,204,69,246,14,4,0,0,0,0,2,204,69,0,0,"",0,0,0,0,288,'',[
|
||||
minilines(204,69,0,0,0,0,0,[
|
||||
mini_line(80,14,4,0,0,0,[
|
||||
str_block(0,80,14,4,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Bold',1,80640,80,14,4,0,-1,0,0,0,0,0,
|
||||
"private data:")])
|
||||
]),
|
||||
mini_line(193,14,3,0,0,0,[
|
||||
str_block(0,193,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,193,14,3,0,0,0,0,0,0,0,
|
||||
"- struct BufferData, a dynamically")])
|
||||
]),
|
||||
mini_line(160,14,3,0,0,0,[
|
||||
str_block(0,160,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,160,14,3,0,0,0,0,0,0,0,
|
||||
"varying byte buffer to which")])
|
||||
]),
|
||||
mini_line(204,14,3,0,0,0,[
|
||||
str_block(0,204,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,204,14,3,0,0,0,0,0,0,0,
|
||||
"data can be prepended or appended")])
|
||||
])
|
||||
])]).
|
||||
text('black',400,146,5,0,1,188,86,247,14,4,0,0,0,0,2,188,86,0,0,"",0,0,0,0,160,'',[
|
||||
minilines(188,86,0,0,0,0,0,[
|
||||
mini_line(105,14,4,0,0,0,[
|
||||
str_block(0,105,14,4,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Bold',1,80640,105,14,4,0,-1,0,0,0,0,0,
|
||||
"public functions:")])
|
||||
]),
|
||||
mini_line(172,14,3,0,0,0,[
|
||||
str_block(0,172,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,172,14,3,0,0,0,0,0,0,0,
|
||||
"- Iterators to move byte buffer")])
|
||||
]),
|
||||
mini_line(171,14,3,0,0,0,[
|
||||
str_block(0,171,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,171,14,3,0,0,0,0,0,0,0,
|
||||
"pointers forward or backward")])
|
||||
]),
|
||||
mini_line(188,14,3,0,0,0,[
|
||||
str_block(0,188,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,188,14,3,0,0,0,0,0,0,0,
|
||||
"- functions to read and write data")])
|
||||
]),
|
||||
mini_line(132,14,3,0,0,0,[
|
||||
str_block(0,132,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,132,14,3,0,-1,0,0,0,0,0,
|
||||
"of various sized chunks")])
|
||||
])
|
||||
])]).
|
||||
box('black','',96,324,304,532,0,3,1,264,0,0,0,0,0,'3',0,[
|
||||
]).
|
||||
text('black',112,454,4,0,1,167,69,265,14,4,0,0,0,0,2,167,69,0,0,"",0,0,0,0,468,'',[
|
||||
minilines(167,69,0,0,0,0,0,[
|
||||
mini_line(80,14,4,0,0,0,[
|
||||
str_block(0,80,14,4,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Bold',1,80640,80,14,4,0,-1,0,0,0,0,0,
|
||||
"private data:")])
|
||||
]),
|
||||
mini_line(167,14,3,0,0,0,[
|
||||
str_block(0,167,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,167,14,3,0,0,0,0,0,0,0,
|
||||
"- singly linked-list of TagData")])
|
||||
]),
|
||||
mini_line(158,14,3,0,0,0,[
|
||||
str_block(0,158,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,158,14,3,0,0,0,0,0,0,0,
|
||||
"structures, with a reference")])
|
||||
]),
|
||||
mini_line(32,14,3,0,0,0,[
|
||||
str_block(0,32,14,3,0,0,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,32,14,3,0,0,0,0,0,0,0,
|
||||
"count")])
|
||||
])
|
||||
])]).
|
||||
text('black',112,326,5,0,1,155,86,266,14,4,0,0,0,0,2,155,86,0,0,"",0,0,0,0,340,'',[
|
||||
minilines(155,86,0,0,0,0,0,[
|
||||
mini_line(105,14,4,0,0,0,[
|
||||
str_block(0,105,14,4,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Bold',1,80640,105,14,4,0,-1,0,0,0,0,0,
|
||||
"public functions:")])
|
||||
]),
|
||||
mini_line(80,14,3,0,0,0,[
|
||||
str_block(0,80,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,80,14,3,0,-1,0,0,0,0,0,
|
||||
"- constructors")])
|
||||
]),
|
||||
mini_line(155,14,3,0,0,0,[
|
||||
str_block(0,155,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,155,14,3,0,-1,0,0,0,0,0,
|
||||
"- templates to add, remove,")])
|
||||
]),
|
||||
mini_line(148,14,3,0,0,0,[
|
||||
str_block(0,148,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,148,14,3,0,-1,0,0,0,0,0,
|
||||
"or peek at Tags of various")])
|
||||
]),
|
||||
mini_line(31,14,3,0,0,0,[
|
||||
str_block(0,31,14,3,0,-1,0,0,0,[
|
||||
str_seg('black','Times-Roman',0,80640,31,14,3,0,-1,0,0,0,0,0,
|
||||
"types")])
|
||||
])
|
||||
])]).
|
||||
poly('black','',2,[
|
||||
59,245,96,320],0,2,1,272,0,0,3,0,0,0,0,'2',0,0,
|
||||
"0","",[
|
||||
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
|
||||
]).
|
||||
poly('black','',2,[
|
||||
123,246,288,320],0,2,1,280,0,0,3,0,0,0,0,'2',0,0,
|
||||
"0","",[
|
||||
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
|
||||
]).
|
||||
poly('black','',2,[
|
||||
141,219,379,147],0,2,1,286,0,0,3,0,0,0,0,'2',0,0,
|
||||
"0","",[
|
||||
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
|
||||
]).
|
||||
poly('black','',2,[
|
||||
132,226,375,335],0,2,1,287,0,0,3,0,0,0,0,'2',0,0,
|
||||
"0","",[
|
||||
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
|
||||
]).
|
||||
BIN
doc/tutorial/figures/pp.dia
Normal file
BIN
doc/tutorial/figures/star.dia
Normal file
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@@ -34,7 +34,7 @@ see this point-to-point network, you can think of an RS-422 (or RS-232 for
|
||||
you old-timers) cable. This topology is shown below.
|
||||
|
||||
@sp 1
|
||||
@center @image{pp,,,,png}
|
||||
@center @image{figures/pp,,,,png}
|
||||
|
||||
@cindex CreateObject
|
||||
@cindex InternetNode
|
||||
@@ -173,7 +173,7 @@ a file for you in the @code{tutorial} directory called @code{tutorial-star.cc}
|
||||
that implements a simple star network as seen below.
|
||||
|
||||
@sp 1
|
||||
@center @image{star,,,,png}
|
||||
@center @image{figures/star,,,,png}
|
||||
|
||||
In order to create a star network, we need to be able to instantiate some
|
||||
number (greater than one) of net devices on a node. In the name of simplicity
|
||||
@@ -506,7 +506,7 @@ configured with a lower bandwidth than the bus elements to provide a
|
||||
The following is a representation of the topology.
|
||||
|
||||
@sp 1
|
||||
@center @image{dumbbell,,,,png}
|
||||
@center @image{figures/dumbbell,,,,png}
|
||||
|
||||
We have provided a file that constructs this dumbbell network and creates
|
||||
enough data flowing across the choke point that some packets will be dropped.
|
||||
|
||||
620
doc/tutorial/packets.texi
Normal file
@@ -0,0 +1,620 @@
|
||||
@node ns-3 Packets
|
||||
@chapter ns-3 Packets
|
||||
|
||||
The design of the Packet framework of @emph{ns} was heavily guided by a few
|
||||
important use-cases:
|
||||
@itemize @bullet
|
||||
@item avoid changing the core of the simulator to introduce
|
||||
new types of packet headers or trailers
|
||||
@item maximize the ease of integration with real-world code
|
||||
and systems
|
||||
@item make it easy to support fragmentation, defragmentation,
|
||||
and, concatenation which are important, especially in wireless systems.
|
||||
@item make memory management of this object efficient
|
||||
@item allow actual application data or dummy application bytes for
|
||||
emulated applications
|
||||
@end itemize
|
||||
|
||||
@emph{ns} Packet objects contain a buffer of bytes: protocol headers and
|
||||
trailers are serialized in this buffer of bytes using user-provided
|
||||
serialization and deserialization routines. The content of this byte
|
||||
buffer is expected to match bit-for-bit the content of a real packet on
|
||||
a real network implementing the protocol of interest.
|
||||
|
||||
Fragmentation and defragmentation are quite natural to implement within
|
||||
this context: since we have a buffer of real bytes, we can split it in
|
||||
multiple fragments and re-assemble these fragments. We expect that this
|
||||
choice will make it really easy to wrap our Packet data structure within
|
||||
Linux-style skb or BSD-style mbuf to integrate real-world kernel code in
|
||||
the simulator. We also expect that performing a real-time plug of the
|
||||
simulator to a real-world network will be easy.
|
||||
|
||||
Because we understand that simulation developers often wish to store in
|
||||
packet objects data which is not found in the real packets (such as
|
||||
timestamps or any kind of similar in-band data), the @emph{ns} Packet class
|
||||
can also store extra per-packet "Tags" which are 16 bytes blobs of data.
|
||||
Any Packet can store any number of unique Tags, each of which is
|
||||
uniquely identified by its C++ type. These tags make it easy to attach
|
||||
per-model data to a packet without having to patch the main Packet
|
||||
class or Packet facilities.
|
||||
|
||||
Memory management of Packet objects is entirely automatic and extremely
|
||||
efficient: memory for the application-level payload can be modelized by
|
||||
a virtual buffer of zero-filled bytes for which memory is never allocated
|
||||
unless explicitely requested by the user or unless the packet is fragmented.
|
||||
Furthermore, copying, adding, and, removing headers or trailers to a packet
|
||||
has been optimized to be virtually free through a technique known as
|
||||
Copy On Write.
|
||||
|
||||
Packets (messages) are fundamental objects in the simulator and
|
||||
their design is important from a performance and resource management
|
||||
perspective. There
|
||||
are various ways to design the simulation packet, and tradeoffs
|
||||
among the different approaches. In particular, there is a
|
||||
tension between ease-of-use, performance, and safe interface
|
||||
design.
|
||||
|
||||
There are a few requirements on this object design:
|
||||
@itemize @bullet
|
||||
@item Creation, management, and deletion of this object
|
||||
should be as simple as possible, while avoiding the
|
||||
chance for memory leaks and/or heap corruption;
|
||||
@item Packets should support serialization and deserialization
|
||||
so that network emulation is supported;
|
||||
@item Packets should support fragmentation and concatenation
|
||||
(multiple packets in a data link frame), especially for wireless
|
||||
support;
|
||||
@item It should be natural for packets to carry actual application
|
||||
data, or if there is only an emulated application and there is
|
||||
no need to carry dummy bytes, smaller packets could be used with
|
||||
just the headers and a record of the payload size, but not actual
|
||||
application bytes, conveyed in the simulated packet.
|
||||
@item Packets should facilitate BSD-like operations on mbufs, for
|
||||
support of ported operating system stacks.
|
||||
@item Additional side-information should be supported, such as
|
||||
a tag for cross-layer information.
|
||||
@end itemize
|
||||
|
||||
@section Packet design overview
|
||||
|
||||
Unlike @emph{ns-2}, in which Packet objects contain a buffer of C++
|
||||
structures corresponding to protocol headers, each network packet in
|
||||
@emph{ns-3} contains a byte Buffer and a list of Tags:
|
||||
@itemize @bullet
|
||||
@item The byte buffer stores the serialized content of the chunks
|
||||
added to a packet. The serialized representation of these chunks is
|
||||
expected to match that of real network packets bit for bit
|
||||
(although nothing forces you to do this) which means that the content
|
||||
of a packet buffer is expected to be that of a real packet.
|
||||
Packets can also be created with an arbitrary zero-filled payload
|
||||
for which no real memory is allocated.
|
||||
@item The list of tags stores an arbitrarily large set of arbitrary
|
||||
user-provided data structures in the packet. Each Tag is uniquely
|
||||
identified by its type; only one instance of each
|
||||
type of data structure is allowed in a list of tags. These tags typically
|
||||
contain per-packet cross-layer information or flow identifiers (i.e.,
|
||||
things that you wouldn't find in the bits on the wire). Each tag
|
||||
stored in the tag list can be at most 16 bytes.
|
||||
Trying to attach bigger data structures will trigger
|
||||
crashes at runtime. The 16 byte limit is a modifiable compilation
|
||||
constant.
|
||||
@end itemize
|
||||
|
||||
@float Figure,fig:packets
|
||||
@caption{Implementation overview of Packet class.}
|
||||
@image{figures/packet}
|
||||
@end float
|
||||
|
||||
Figure @ref{fig:packets} is a high-level overview of the Packet
|
||||
implementation; more detail on the byte Buffer implementation
|
||||
is provided later in Figure @ref{fig:buffer}.
|
||||
In \nsthree, the Packet byte buffer is analogous to a Linux skbuff
|
||||
or BSD mbuf; it is a serialized representation of the actual
|
||||
data in the packet. The tag list is a container for extra
|
||||
items useful for simulation convenience; if a Packet is converted
|
||||
to an emulated packet and put over an actual network, the tags
|
||||
are stripped off and the byte buffer is copied directly
|
||||
into a real packet.
|
||||
|
||||
The Packet class has value semantics: it can be freely copied around,
|
||||
allocated on the stack, and passed to functions as arguments. Whenever
|
||||
an instance is copied, the full underlying data is not copied; it
|
||||
has ``copy-on-write'' (COW) semantics. Packet instances can be passed
|
||||
by value to function arguments without any performance hit.
|
||||
|
||||
The fundamental classes for adding to and removing from the byte
|
||||
buffer are @code{class Header} and @code{class Trailer}.
|
||||
Headers are more common but the below discussion also largely applies to
|
||||
protocols using trailers. Every protocol header that needs to
|
||||
be inserted and removed from a Packet instance should derive from
|
||||
the abstract Header base class and implement the private pure
|
||||
virtual methods listed below:
|
||||
@itemize @bullet
|
||||
@item @code{ns3::Header::SerializeTo()}
|
||||
@item @code{ns3::Header::DeserializeFrom()}
|
||||
@item @code{ns3::Header::GetSerializedSize()}
|
||||
@item @code{ns3::Header::PrintTo()}
|
||||
@end itemize
|
||||
Basically, the first three functions are used to serialize and deserialize
|
||||
protocol control information to/from a Buffer. For example,
|
||||
one may define @code{class TCPHeader : public Header}. The
|
||||
TCPHeader object will typically consist of some private data
|
||||
(like a sequence number) and public interface access functions
|
||||
(such as checking the bounds of an input). But the underlying
|
||||
representation of the TCPHeader in a Packet Buffer is 20 serialized
|
||||
bytes (plus TCP options). The TCPHeader::SerializeTo() function would
|
||||
therefore be designed to write these 20 bytes properly into
|
||||
the packet, in network byte order. The last function is used
|
||||
to define how the Header object prints itself onto an output stream.
|
||||
|
||||
Similarly, user-defined Tags can be appended to the packet.
|
||||
Unlike Headers, Tags are not serialized into a contiguous buffer
|
||||
but are stored in an array. By default, Tags are limited to 16 bytes in
|
||||
size. Tags can be flexibly defined to be any type, but there
|
||||
can only be one instance of any particular object type in
|
||||
the Tags buffer at any time. The implementation makes use
|
||||
of templates to generate the proper set of Add(), Remove(),
|
||||
and Peek() functions for each Tag type.
|
||||
|
||||
@section Packet interface
|
||||
|
||||
The public member functions of a Packet object are as follows:
|
||||
|
||||
@subsection Constructors
|
||||
@verbatim
|
||||
/**
|
||||
* Create an empty packet with a new uid (as returned
|
||||
* by getUid).
|
||||
*/
|
||||
Packet ();
|
||||
/**
|
||||
* Create a packet with a zero-filled payload.
|
||||
* The memory necessary for the payload is not allocated:
|
||||
* it will be allocated at any later point if you attempt
|
||||
* to fragment this packet or to access the zero-filled
|
||||
* bytes. The packet is allocated with a new uid (as
|
||||
* returned by getUid).
|
||||
*
|
||||
* \param size the size of the zero-filled payload
|
||||
*/
|
||||
Packet (uint32_t size);
|
||||
@end verbatim
|
||||
|
||||
@subsection Adding and removing Buffer data
|
||||
The below code is reproduced for Header class only; similar functions
|
||||
exist for Trailers.
|
||||
@verbatim
|
||||
/**
|
||||
* Add header to this packet. This method invokes the
|
||||
* ns3::Header::serializeTo method to request the header to serialize
|
||||
* itself in the packet buffer.
|
||||
*
|
||||
* \param header a reference to the header to add to this packet.
|
||||
*/
|
||||
void Add (Header const &header);
|
||||
/**
|
||||
* Deserialize header from this packet. This method invokes the
|
||||
* ns3::Header::deserializeFrom method to request the header to deserialize
|
||||
* itself from the packet buffer. This method does not remove
|
||||
* the data from the buffer. It merely reads it.
|
||||
*
|
||||
* \param header a reference to the header to deserialize from the buffer
|
||||
*/
|
||||
void Peek (Header &header);
|
||||
/**
|
||||
* Remove a deserialized header from the internal buffer.
|
||||
* This method removes the bytes read by Packet::peek from
|
||||
* the packet buffer.
|
||||
*
|
||||
* \param header a reference to the header to remove from the internal buffer.
|
||||
*/
|
||||
void Remove (Header const &header);
|
||||
/**
|
||||
* Add trailer to this packet. This method invokes the
|
||||
* ns3::Trailer::serializeTo method to request the trailer to serialize
|
||||
* itself in the packet buffer.
|
||||
*
|
||||
* \param trailer a reference to the trailer to add to this packet.
|
||||
*/
|
||||
@end verbatim
|
||||
|
||||
@subsection Adding and removing Tags
|
||||
@verbatim
|
||||
/**
|
||||
* Attach a tag to this packet. The tag is fully copied
|
||||
* in a packet-specific internal buffer. This operation
|
||||
* is expected to be really fast.
|
||||
*
|
||||
* \param tag a pointer to the tag to attach to this packet.
|
||||
*/
|
||||
template <typename T>
|
||||
void AddTag (T const &tag);
|
||||
/**
|
||||
* Remove a tag from this packet. The data stored internally
|
||||
* for this tag is copied in the input tag if an instance
|
||||
* of this tag type is present in the internal buffer. If this
|
||||
* tag type is not present, the input tag is not modified.
|
||||
*
|
||||
* This operation can be potentially slow and might trigger
|
||||
* unexpectedly large memory allocations. It is thus
|
||||
* usually a better idea to create a copy of this packet,
|
||||
* and invoke removeAllTags on the copy to remove all
|
||||
* tags rather than remove the tags one by one from a packet.
|
||||
*
|
||||
* \param tag a pointer to the tag to remove from this packet
|
||||
* \returns true if an instance of this tag type is stored
|
||||
* in this packet, false otherwise.
|
||||
*/
|
||||
template <typename T>
|
||||
bool RemoveTag (T &tag);
|
||||
/**
|
||||
* Copy a tag stored internally to the input tag. If no instance
|
||||
* of this tag is present internally, the input tag is not modified.
|
||||
*
|
||||
* \param tag a pointer to the tag to read from this packet
|
||||
* \returns true if an instance of this tag type is stored
|
||||
* in this packet, false otherwise.
|
||||
*/
|
||||
template <typename T>
|
||||
bool PeekTag (T &tag) const;
|
||||
/**
|
||||
* Remove all the tags stored in this packet. This operation is
|
||||
* much much faster than invoking removeTag n times.
|
||||
*/
|
||||
void RemoveAllTags (void);
|
||||
@end verbatim
|
||||
|
||||
@subsection Fragmentation
|
||||
@verbatim
|
||||
/**
|
||||
* Create a new packet which contains a fragment of the original
|
||||
* packet. The returned packet shares the same uid as this packet.
|
||||
*
|
||||
* \param start offset from start of packet to start of fragment to create
|
||||
* \param length length of fragment to create
|
||||
* \returns a fragment of the original packet
|
||||
*/
|
||||
Packet CreateFragment (uint32_t start, uint32_t length) const;
|
||||
|
||||
/**
|
||||
* Concatenate the input packet at the end of the current
|
||||
* packet. This does not alter the uid of either packet.
|
||||
*
|
||||
* \param packet packet to concatenate
|
||||
*/
|
||||
void addAtEnd (Packet packet);
|
||||
|
||||
/oncatenate the input packet at the end of the current
|
||||
* packet. This does not alter the uid of either packet.
|
||||
*
|
||||
* \param packet packet to concatenate
|
||||
*/
|
||||
void AddAtEnd (Packet packet);
|
||||
/**
|
||||
* Concatenate the fragment of the input packet identified
|
||||
* by the offset and size parameters at the end of the current
|
||||
* packet. This does not alter the uid of either packet.
|
||||
*
|
||||
* \param packet to concatenate
|
||||
* \param offset offset of fragment to copy from the start of the input packet
|
||||
* \param size size of fragment of input packet to copy.
|
||||
*/
|
||||
void AddAtEnd (Packet packet, uint32_t offset, uint32_t size);
|
||||
/**
|
||||
* Remove size bytes from the end of the current packet
|
||||
* It is safe to remove more bytes that what is present in
|
||||
* the packet.
|
||||
*
|
||||
* \param size number of bytes from remove
|
||||
*/
|
||||
void RemoveAtEnd (uint32_t size);
|
||||
/**
|
||||
* Remove size bytes from the start of the current packet.
|
||||
* It is safe to remove more bytes that what is present in
|
||||
* the packet.
|
||||
*
|
||||
* \param size number of bytes from remove
|
||||
*/
|
||||
void RemoveAtStart (uint32_t size);
|
||||
@end verbatim
|
||||
|
||||
@subsection Miscellaneous
|
||||
@verbatim
|
||||
/**
|
||||
* \returns the size in bytes of the packet (including the zero-filled
|
||||
* initial payload)
|
||||
*/
|
||||
uint32_t GetSize (void) const;
|
||||
/**
|
||||
* If you try to change the content of the buffer
|
||||
* returned by this method, you will die.
|
||||
*
|
||||
* \returns a pointer to the internal buffer of the packet.
|
||||
*/
|
||||
uint8_t const *PeekData (void) const;
|
||||
/**
|
||||
* A packet is allocated a new uid when it is created
|
||||
* empty or with zero-filled payload.
|
||||
*
|
||||
* \returns an integer identifier which uniquely
|
||||
* identifies this packet.
|
||||
*/
|
||||
uint32_t GetUid (void) const;
|
||||
@end verbatim
|
||||
|
||||
@section Using Headers
|
||||
@emph{walk through an example of adding a UDP header}
|
||||
|
||||
@section Using Tags
|
||||
@emph{walk through an example of adding a flow ID}
|
||||
|
||||
@section Using Fragmentation
|
||||
@emph{walk through an example of link-layer fragmentation/reassembly}
|
||||
|
||||
@section Sample program
|
||||
The below sample program (from @code{ns3/samples/main-packet.cc}) illustrates
|
||||
some use of the Packet, Header, and Tag classes.
|
||||
|
||||
@verbatim
|
||||
/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/header.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
/* A sample Header implementation
|
||||
*/
|
||||
class MyHeader : public Header {
|
||||
public:
|
||||
MyHeader ();
|
||||
virtual ~MyHeader ();
|
||||
|
||||
void SetData (uint16_t data);
|
||||
uint16_t GetData (void) const;
|
||||
private:
|
||||
virtual void PrintTo (std::ostream &os) const;
|
||||
virtual void SerializeTo (Buffer::Iterator start) const;
|
||||
virtual void DeserializeFrom (Buffer::Iterator start);
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
|
||||
uint16_t m_data;
|
||||
};
|
||||
|
||||
MyHeader::MyHeader ()
|
||||
{}
|
||||
MyHeader::~MyHeader ()
|
||||
{}
|
||||
void
|
||||
MyHeader::PrintTo (std::ostream &os) const
|
||||
{
|
||||
os << "MyHeader data=" << m_data << std::endl;
|
||||
}
|
||||
uint32_t
|
||||
MyHeader::GetSerializedSize (void) const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
void
|
||||
MyHeader::SerializeTo (Buffer::Iterator start) const
|
||||
{
|
||||
// serialize in head of buffer
|
||||
start.WriteHtonU16 (m_data);
|
||||
}
|
||||
void
|
||||
MyHeader::DeserializeFrom (Buffer::Iterator start)
|
||||
{
|
||||
// deserialize from head of buffer
|
||||
m_data = start.ReadNtohU16 ();
|
||||
}
|
||||
|
||||
void
|
||||
MyHeader::SetData (uint16_t data)
|
||||
{
|
||||
m_data = data;
|
||||
}
|
||||
uint16_t
|
||||
MyHeader::GetData (void) const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
/* A sample Tag implementation
|
||||
*/
|
||||
struct MyTag {
|
||||
uint16_t m_streamId;
|
||||
};
|
||||
|
||||
static TagRegistration<struct MyTag> g_MyTagRegistration ("ns3::MyTag", 0);
|
||||
|
||||
|
||||
static void
|
||||
Receive (Packet p)
|
||||
{
|
||||
MyHeader my;
|
||||
p.Peek (my);
|
||||
p.Remove (my);
|
||||
std::cout << "received data=" << my.GetData () << std::endl;
|
||||
struct MyTag myTag;
|
||||
p.PeekTag (myTag);
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
Packet p;
|
||||
MyHeader my;
|
||||
my.SetData (2);
|
||||
std::cout << "send data=2" << std::endl;
|
||||
p.Add (my);
|
||||
struct MyTag myTag;
|
||||
myTag.m_streamId = 5;
|
||||
p.AddTag (myTag);
|
||||
Receive (p);
|
||||
return 0;
|
||||
}
|
||||
@end verbatim
|
||||
|
||||
@section Implementation details
|
||||
|
||||
@subsection Private member variables
|
||||
|
||||
A Packet object's interface provides access to some private
|
||||
data:
|
||||
@verbatim
|
||||
Buffer m_buffer;
|
||||
Tags m_tags;
|
||||
uint32_t m_uid;
|
||||
static uint32_t m_global_uid;
|
||||
@end verbatim
|
||||
Each Packet has a Buffer and a Tags object, and a 32-bit unique ID (m\_uid).
|
||||
A static member variable keeps track of the UIDs allocated. Note
|
||||
that real network packets do not have a UID; the UID is therefore an
|
||||
instance of data that normally would be stored as a Tag in the packet.
|
||||
However, it was felt that a UID is a special case that is so often
|
||||
used in simulations that it would be more convenient to store it
|
||||
in a member variable.
|
||||
|
||||
@subsection Buffer implementation
|
||||
|
||||
Class Buffer represents a buffer of bytes. Its size is
|
||||
automatically adjusted to hold any data prepended
|
||||
or appended by the user. Its implementation is optimized
|
||||
to ensure that the number of buffer resizes is minimized,
|
||||
by creating new Buffers of the maximum size ever used.
|
||||
The correct maximum size is learned at runtime during use by
|
||||
recording the maximum size of each packet.
|
||||
|
||||
Authors of new Header or Trailer classes need to know the public
|
||||
API of the Buffer class. (add summary here)
|
||||
|
||||
The byte buffer is implemented as follows:
|
||||
@verbatim
|
||||
struct BufferData {
|
||||
uint32_t m_count;
|
||||
uint32_t m_size;
|
||||
uint32_t m_initialStart;
|
||||
uint32_t m_dirtyStart;
|
||||
uint32_t m_dirtySize;
|
||||
uint8_t m_data[1];
|
||||
};
|
||||
struct BufferData *m_data;
|
||||
uint32_t m_zeroAreaSize;
|
||||
uint32_t m_start;
|
||||
uint32_t m_size;
|
||||
@end verbatim
|
||||
|
||||
@itemize @bullet
|
||||
@item @code{BufferData::m_count}: reference count for BufferData structure
|
||||
@item @code{BufferData::m_size}: size of data buffer stored in BufferData structure
|
||||
@item @code{BufferData::m_initialStart}: offset from start of data buffer where data was first inserted
|
||||
@item @code{BufferData::m_dirtyStart}: offset from start of buffer where every Buffer which holds a reference to this BufferData instance have written data so far
|
||||
@item @code{BufferData::m_dirtySize}: size of area where data has been written so far
|
||||
@item @code{BufferData::m_data}: pointer to data buffer
|
||||
@item @code{Buffer::m_zeroAreaSize}: size of zero area which extends before @code{m_initialStart}
|
||||
@item @code{Buffer::m_start}: offset from start of buffer to area used by this buffer
|
||||
@item @code{Buffer::m_size}: size of area used by this Buffer in its BufferData structure
|
||||
@end itemize
|
||||
|
||||
@float Figure,fig:buffer
|
||||
@caption{Implementation overview of a packet's byte Buffer.}
|
||||
@image{figures/buffer,15cm}
|
||||
@end float
|
||||
|
||||
This data structure is summarized in Figure @ref{fig:buffer}.
|
||||
Each Buffer holds a pointer to an instance of a BufferData. Most
|
||||
Buffers should be able to share the same underlying BufferData and
|
||||
thus simply increase the BufferData's reference count. If they have to
|
||||
change the content of a BufferData inside the Dirty Area, and if the
|
||||
reference count is not one, they first create a copy of the BufferData and
|
||||
then complete their state-changing operation.
|
||||
|
||||
@subsection Tags implementation
|
||||
Tags are implemented by a single pointer which points to the start of a
|
||||
linked list ofTagData data structures. Each TagData structure points
|
||||
to the next TagData in the list (its next pointer contains zero to
|
||||
indicate the end of the linked list). Each TagData contains an integer
|
||||
unique id which identifies the type of the tag stored in the TagData.
|
||||
@verbatim
|
||||
struct TagData {
|
||||
struct TagData *m_next;
|
||||
uint32_t m_id;
|
||||
uint32_t m_count;
|
||||
uint8_t m_data[Tags::SIZE];
|
||||
};
|
||||
class Tags {
|
||||
struct TagData *m_next;
|
||||
};
|
||||
@end verbatim
|
||||
|
||||
Adding a tag is a matter of inserting a new TagData at the head of
|
||||
the linked list. Looking at a tag requires you to find the relevant
|
||||
TagData in the linked list and copy its data into the user data
|
||||
structure. Removing a tag and updating the content of a tag
|
||||
requires a deep copy of the linked list before performing this operation.
|
||||
On the other hand, copying a Packet and its tags is a matter of
|
||||
copying the TagData head pointer and incrementing its reference count.
|
||||
|
||||
Tags are found by the unique mapping betweent the Tag type and
|
||||
its underlying id. This is why at most one instance of any Tag
|
||||
can be stored in a packet. The mapping between Tag type and
|
||||
underlying id is performed by a registration as follows:
|
||||
@verbatim
|
||||
/* A sample Tag implementation
|
||||
*/
|
||||
struct MyTag {
|
||||
uint16_t m_streamId;
|
||||
};
|
||||
@end verbatim
|
||||
|
||||
@emph{add description of TagRegistration for printing}
|
||||
|
||||
@subsection Memory management
|
||||
|
||||
@emph{Describe free list.}
|
||||
|
||||
@emph{Describe dataless vs. data-full packets.}
|
||||
|
||||
@subsection Copy-on-write semantics
|
||||
The current implementation of the byte buffers and tag list is based
|
||||
on COW (Copy On Write). An introduction to COW can be found in Scott
|
||||
Meyer's "More Effective C++", items 17 and 29). This design feature
|
||||
and aspects of the public interface borrows from the packet design
|
||||
of the Georgia Tech Network Simulator.
|
||||
This implementation of COW uses a customized reference counting
|
||||
smart pointer class.
|
||||
|
||||
What COW means is that
|
||||
copying packets without modifying them is very cheap (in terms of CPU
|
||||
and memory usage) and modifying them can be also very cheap. What is
|
||||
key for proper COW implementations is being
|
||||
able to detect when a given modification of the state of a packet triggers
|
||||
a full copy of the data prior to the modification: COW systems need
|
||||
to detect when an operation is ``dirty'' and must therefore invoke
|
||||
a true copy.
|
||||
|
||||
Dirty operations:
|
||||
@itemize @bullet
|
||||
@item Packet::RemoveTag()
|
||||
@item Packet::Add()
|
||||
@item both versions of ns3::Packet::AddAtEnd()
|
||||
@end itemize
|
||||
|
||||
Non-dirty operations:
|
||||
@itemize @bullet
|
||||
@item Packet::AddTag()
|
||||
@item Packet::RemoveAllTags()
|
||||
@item Packet::PeekTag()
|
||||
@item Packet::Peek()
|
||||
@item Packet::Remove()
|
||||
@item Packet::CreateFragment()
|
||||
@item Packet::RemoveAtStart()
|
||||
@item Packet::RemoveAtEnd()
|
||||
@end itemize
|
||||
|
||||
Dirty operations will always be slower than non-dirty operations,
|
||||
sometimes by several orders of magnitude. However, even the
|
||||
dirty operations have been optimized for common use-cases which
|
||||
means that most of the time, these operations will not trigger
|
||||
data copies and will thus be still very fast.
|
||||
|
||||
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 7.6 KiB |
@@ -93,7 +93,9 @@ Part 3: Reconfiguring Existing ns-3 Scripts
|
||||
Part 4: Creating New or Revised Topologies
|
||||
* Helper Functions::
|
||||
* Other-network-topologies::
|
||||
Part 5: Extending ns-3
|
||||
Part 5: Key ns-3 objects and systems
|
||||
* ns-3 Packets::
|
||||
Part 6: Extending ns-3
|
||||
* ns-3 Callbacks::
|
||||
* ns-3 routing overview::
|
||||
* Nonlinear-Thinking::
|
||||
@@ -111,8 +113,9 @@ Part 5: Extending ns-3
|
||||
@include attributes.texi
|
||||
@include statistics.texi
|
||||
@include helpers.texi
|
||||
@include packets.texi
|
||||
@include callbacks.texi
|
||||
@include output.texi
|
||||
@c @include output.texi
|
||||
@include routing.texi
|
||||
@c @include other.texi
|
||||
@include troubleshoot.texi
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 University of Washington
|
||||
* Copyright (c) 2007, 2008 University of Washington
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -14,8 +14,6 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Craig Dowell <craigdo@ee.washington.edu>
|
||||
*/
|
||||
|
||||
#include "point-to-point-channel.h"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2005,2006 INRIA
|
||||
* Copyright (c) 2007, 2008 University of Washington
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -14,9 +14,6 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Craig Dowell <craigdo@ee.washington.edu>
|
||||
* Revised: George Riley <riley@ece.gatech.edu>
|
||||
*/
|
||||
|
||||
#include "ns3/log.h"
|
||||
@@ -389,5 +386,4 @@ PointToPointNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
|
||||
m_rxCallback = cb;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 University of Washington
|
||||
* Copyright (c) 2007, 2008 University of Washington
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -14,8 +14,6 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Craig Dowell <craigdo@ee.washington.edu>
|
||||
*/
|
||||
|
||||
#ifndef POINT_TO_POINT_NET_DEVICE_H
|
||||
|
||||
@@ -1,11 +1,45 @@
|
||||
/**
|
||||
* \ingroup devices
|
||||
* \defgroup PointToPoint Point-to-Point Models
|
||||
* \defgroup PointToPoint Point-to-Point Model
|
||||
*
|
||||
* \section Point-to-Point Models
|
||||
* \section Point-to-Point Model
|
||||
*
|
||||
* The set of Point-to-Point models provides an abstrated point-to-point link
|
||||
* model, that simulates transmission delay (finite data rate) and
|
||||
* propagation delay, and can also optionally include an error model
|
||||
* (ns3::ErrorModel).
|
||||
* The ns-3 point-to-point model is of a very simple point to point data link
|
||||
* connecting exactly two ns3::PointToPointNetDevice devices over an
|
||||
* ns3::PointToPointChannel. This can be viewed as equivalent to a full
|
||||
* duplex RS-232 or RS-422 link with null modem and no handshaking.
|
||||
*
|
||||
* Data is encapsulated in the Point-to-Point Protocol (PPP -- RFC 1661),
|
||||
* however the Link Control Protocol (LCP) and associated state machine is
|
||||
* not implemented. The PPP link is assumed to be established and
|
||||
* authenticated at all times.
|
||||
*
|
||||
* Data is not framed, therefore Address and Control fields will not be found.
|
||||
* Since the data is not framed, there is no need to provide Flag Sequence and
|
||||
* Control Escape octets, nor is a Frame Check Sequence appended. All that is
|
||||
* required to implement non-framed PPP is to prepend the PPP protocol number
|
||||
* for IP Version 4 which is the sixteen-bit number 0x21 (see
|
||||
* http://www.iana.org/assignments/ppp-numbers).
|
||||
*
|
||||
* The ns3::PointToPointNetDevice provides following Attributes:
|
||||
*
|
||||
* - Address: The ns3::Mac48Address of the device (if desired);
|
||||
* - DataRate: The data rate of the device;
|
||||
* - TxQueue: The trasmit queue used by the device;
|
||||
* - InterframeGap: The optional time to wait between "frames";
|
||||
* - Rx: A trace source for received packets;
|
||||
* - Drop: A trace source for dropped packets.
|
||||
*
|
||||
* The ns3::PointToPointNetDevice supports the assignment of a "receive error
|
||||
* model." This is an ns3::ErrorModel object that is used to simulate data
|
||||
* corruption on the link.
|
||||
*
|
||||
* The point to point net devices are connected via an
|
||||
* ns3::PointToPointChannel. This channel models two wires transmitting bits
|
||||
* at the data rate specified by the source net device. There is no overhead
|
||||
* beyond the eight bits per byte of the packet sent. That is, we do not
|
||||
* model Flag Sequences, Frame Check Sequences nor do we "escape" any data.
|
||||
*
|
||||
* The ns3::PointToPointChannel does model a speed-of-light delay which can
|
||||
* be accessed via the attribute "Delay."
|
||||
*/
|
||||
|
||||
@@ -55,7 +55,7 @@ PppHeader::GetInstanceTypeId (void) const
|
||||
void
|
||||
PppHeader::Print (std::ostream &os) const
|
||||
{
|
||||
os << "Point-to-Point Protocol: IP (0x0021)" << std::endl;
|
||||
os << "Point-to-Point Protocol: IP (0x0021)";
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
||||
@@ -1275,7 +1275,7 @@ GlobalRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v)
|
||||
// the local side of the point-to-point links found on the node described by
|
||||
// the vertex <v>.
|
||||
//
|
||||
for (uint32_t j = 0; j < nLinkRecords; j += 2)
|
||||
for (uint32_t j = 0; j < nLinkRecords; ++j)
|
||||
{
|
||||
//
|
||||
// We are only concerned about point-to-point links
|
||||
|
||||