diff --git a/doc/tutorial/Makefile b/doc/tutorial/Makefile
index a076e334f..b229ba74c 100644
--- a/doc/tutorial/Makefile
+++ b/doc/tutorial/Makefile
@@ -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/
diff --git a/doc/tutorial/dumbbell.png b/doc/tutorial/dumbbell.png
deleted file mode 100644
index 0fc3d8c9e..000000000
Binary files a/doc/tutorial/dumbbell.png and /dev/null differ
diff --git a/doc/tutorial/figures/README b/doc/tutorial/figures/README
index fe69d95cb..4f63268dc 100644
--- a/doc/tutorial/figures/README
+++ b/doc/tutorial/figures/README
@@ -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
diff --git a/doc/tutorial/figures/buffer.dia b/doc/tutorial/figures/buffer.dia
new file mode 100644
index 000000000..b1868f7f4
--- /dev/null
+++ b/doc/tutorial/figures/buffer.dia
@@ -0,0 +1,1623 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ #A4#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Count#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Size#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Initial Start#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Dirty Start#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Unused Area#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Dirty Size#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Dirty Area#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Virtual Zero Area#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Unused Area#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Data#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Zero Area Size#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Used start#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Used Size#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Data#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Zero Area Size#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Used start#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Used Size#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Used#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Used#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Virtual Zero Area#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Buffer#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #BufferData#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #Buffer#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/tutorial/figures/dumbbell.dia b/doc/tutorial/figures/dumbbell.dia
new file mode 100644
index 000000000..91af27577
Binary files /dev/null and b/doc/tutorial/figures/dumbbell.dia differ
diff --git a/doc/tutorial/oneobj.png b/doc/tutorial/figures/oneobj.png
similarity index 100%
rename from doc/tutorial/oneobj.png
rename to doc/tutorial/figures/oneobj.png
diff --git a/doc/tutorial/figures/packet.obj b/doc/tutorial/figures/packet.obj
new file mode 100644
index 000000000..c6a66cd71
--- /dev/null
+++ b/doc/tutorial/figures/packet.obj
@@ -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'],[
+]).
diff --git a/doc/tutorial/figures/pp.dia b/doc/tutorial/figures/pp.dia
new file mode 100644
index 000000000..2c81980a5
Binary files /dev/null and b/doc/tutorial/figures/pp.dia differ
diff --git a/doc/tutorial/figures/star.dia b/doc/tutorial/figures/star.dia
new file mode 100644
index 000000000..6b826b313
Binary files /dev/null and b/doc/tutorial/figures/star.dia differ
diff --git a/doc/tutorial/threeobj.png b/doc/tutorial/figures/threeobj.png
similarity index 100%
rename from doc/tutorial/threeobj.png
rename to doc/tutorial/figures/threeobj.png
diff --git a/doc/tutorial/other.texi b/doc/tutorial/other.texi
index efa83a083..3e4a63a7b 100644
--- a/doc/tutorial/other.texi
+++ b/doc/tutorial/other.texi
@@ -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.
diff --git a/doc/tutorial/packets.texi b/doc/tutorial/packets.texi
new file mode 100644
index 000000000..cc00e0094
--- /dev/null
+++ b/doc/tutorial/packets.texi
@@ -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
+ 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
+ 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
+ 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
+
+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 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.
+
diff --git a/doc/tutorial/pp.png b/doc/tutorial/pp.png
deleted file mode 100644
index 84b76d6df..000000000
Binary files a/doc/tutorial/pp.png and /dev/null differ
diff --git a/doc/tutorial/star.png b/doc/tutorial/star.png
deleted file mode 100644
index c580d0305..000000000
Binary files a/doc/tutorial/star.png and /dev/null differ
diff --git a/doc/tutorial/tutorial.texi b/doc/tutorial/tutorial.texi
index 737041b61..1af725da1 100644
--- a/doc/tutorial/tutorial.texi
+++ b/doc/tutorial/tutorial.texi
@@ -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
diff --git a/src/devices/point-to-point/point-to-point-channel.cc b/src/devices/point-to-point/point-to-point-channel.cc
index 83a7abb46..94d3c6e40 100644
--- a/src/devices/point-to-point/point-to-point-channel.cc
+++ b/src/devices/point-to-point/point-to-point-channel.cc
@@ -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
*/
#include "point-to-point-channel.h"
diff --git a/src/devices/point-to-point/point-to-point-net-device.cc b/src/devices/point-to-point/point-to-point-net-device.cc
index fb7d51110..c752e9023 100644
--- a/src/devices/point-to-point/point-to-point-net-device.cc
+++ b/src/devices/point-to-point/point-to-point-net-device.cc
@@ -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
- * Revised: George Riley
*/
#include "ns3/log.h"
@@ -389,5 +386,4 @@ PointToPointNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
m_rxCallback = cb;
}
-
} // namespace ns3
diff --git a/src/devices/point-to-point/point-to-point-net-device.h b/src/devices/point-to-point/point-to-point-net-device.h
index ebfaf8239..b42ed4fe2 100644
--- a/src/devices/point-to-point/point-to-point-net-device.h
+++ b/src/devices/point-to-point/point-to-point-net-device.h
@@ -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
*/
#ifndef POINT_TO_POINT_NET_DEVICE_H
diff --git a/src/devices/point-to-point/point-to-point.h b/src/devices/point-to-point/point-to-point.h
index 3ae8a24e3..f6799ceec 100644
--- a/src/devices/point-to-point/point-to-point.h
+++ b/src/devices/point-to-point/point-to-point.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."
*/
diff --git a/src/devices/point-to-point/ppp-header.cc b/src/devices/point-to-point/ppp-header.cc
index 909e9f1b9..7cc62d585 100644
--- a/src/devices/point-to-point/ppp-header.cc
+++ b/src/devices/point-to-point/ppp-header.cc
@@ -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
diff --git a/src/routing/global-routing/global-route-manager-impl.cc b/src/routing/global-routing/global-route-manager-impl.cc
index 68d5dc43a..bf40994b0 100644
--- a/src/routing/global-routing/global-route-manager-impl.cc
+++ b/src/routing/global-routing/global-route-manager-impl.cc
@@ -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 .
//
- 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