chapter on Node and internet stack, for manual
authorTom Henderson <tomh@tomh.org>
Mon, 30 Jun 2008 22:41:22 -0700
changeset 3362 9a6f1b3c6e0b
parent 3361 b8db6cd10444
child 3363 33d1ca2e4ba4
chapter on Node and internet stack, for manual
doc/manual/Makefile
doc/manual/figures/internet-node-recv.obj
doc/manual/figures/internet-node-send.obj
doc/manual/figures/node.obj
doc/manual/manual.texi
doc/manual/node.texi
--- a/doc/manual/Makefile	Mon Jun 30 14:17:19 2008 -0700
+++ b/doc/manual/Makefile	Mon Jun 30 22:41:22 2008 -0700
@@ -8,8 +8,7 @@
 SPLIT = --split section
 
 DIA_SOURCES = buffer.dia sockets-overview.dia
-TGIF_SOURCES = packet.obj 
-
+TGIF_SOURCES = packet.obj node.obj internet-node-send.obj internet-node-recv.obj 
 DIA_EPS = ${DIA_SOURCES:.dia=.eps}
 DIA_PNG = ${DIA_SOURCES:.dia=.png}
 DIA_PDF = ${DIA_SOURCES:.dia=.pdf}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/figures/internet-node-recv.obj	Mon Jun 30 22:41:22 2008 -0700
@@ -0,0 +1,380 @@
+%TGIF 4.1.43-QPL
+state(0,37,100.000,154,78,0,16,0,9,1,1,0,0,3,0,1,0,'Times-Roman',0,80640,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,'').
+group([
+rcbox('black','',161,586,241,634,2,1,1,0,16,125,0,0,0,0,'1',0,[
+]),
+text('black',161,605,1,0,1,72,18,124,13,5,0,0,0,0,2,72,18,0,0,"",0,0,0,0,618,'',[
+minilines(72,18,0,0,0,0,0,[
+mini_line(72,13,5,0,0,0,[
+str_block(0,72,13,5,0,0,0,0,0,[
+str_seg('black','Courier',0,80640,72,13,5,0,0,0,0,0,0,0,
+	"NetDevice")])
+])
+])])
+],
+141,0,0,[
+]).
+group([
+rcbox('black','',147,77,255,125,2,1,1,0,16,354,0,0,0,0,'1',0,[
+]),
+text('black',163,96,1,0,1,88,18,353,13,5,0,0,0,0,2,88,18,0,0,"",0,0,0,0,109,'',[
+minilines(88,18,0,0,0,0,0,[
+mini_line(88,13,5,0,0,0,[
+str_block(0,88,13,5,0,0,0,0,0,[
+str_seg('black','Courier',0,80640,88,13,5,0,0,0,0,0,0,0,
+	"Application")])
+])
+])])
+],
+352,0,0,[
+]).
+text('black',202,172,1,1,1,90,17,473,14,3,2,0,0,0,2,90,17,0,0,"",0,0,0,0,186,'',[
+minilines(90,17,0,0,1,0,0,[
+mini_line(90,14,3,0,0,0,[
+str_block(0,90,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,90,14,3,0,0,0,0,0,0,0,
+	"UdpSocketImpl")])
+])
+])]).
+rcbox('black','',132,165,269,198,0,1,1,0,16,474,0,0,0,0,'1',0,[
+]).
+text('black',202,241,1,1,1,78,17,475,14,3,2,0,0,0,2,78,17,0,0,"",0,0,0,0,255,'',[
+minilines(78,17,0,0,1,0,0,[
+mini_line(78,14,3,0,0,0,[
+str_block(0,78,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,78,14,3,0,0,0,0,0,0,0,
+	"Ipv4EndPoint")])
+])
+])]).
+rcbox('black','',132,234,269,267,0,1,1,0,16,476,0,0,0,0,'1',0,[
+]).
+text('black',202,338,1,1,1,88,17,488,14,3,2,0,0,0,2,88,17,0,0,"",0,0,0,0,352,'',[
+minilines(88,17,0,0,1,0,0,[
+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,
+	"UdpL4Protocol")])
+])
+])]).
+rcbox('black','',132,331,269,364,0,1,1,0,16,489,0,0,0,0,'1',0,[
+]).
+text('black',202,434,1,1,1,90,17,490,14,3,2,0,0,0,2,90,17,0,0,"",0,0,0,0,448,'',[
+minilines(90,17,0,0,1,0,0,[
+mini_line(90,14,3,0,0,0,[
+str_block(0,90,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,90,14,3,0,0,0,0,0,0,0,
+	"Ipv4L3Protocol")])
+])
+])]).
+rcbox('black','',132,427,269,460,0,1,1,0,16,491,0,0,0,0,'1',0,[
+]).
+text('black',585,11,1,0,1,179,17,496,14,3,0,0,0,0,2,179,17,0,0,"",0,0,0,0,25,'',[
+minilines(179,17,0,0,0,0,0,[
+mini_line(179,14,3,0,0,0,[
+str_block(0,179,14,3,0,-2,0,0,0,[
+str_seg('black','Times-Roman',0,80640,179,14,3,0,-2,1,0,0,0,0,
+	"Step in packet receive process:")])
+])
+])]).
+text('black',480,595,1,0,1,408,17,498,14,3,0,0,0,0,2,408,17,0,0,"",0,0,0,0,609,'',[
+minilines(408,17,0,0,0,0,0,[
+mini_line(408,14,3,0,0,0,[
+str_block(0,408,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,408,14,3,0,0,0,0,0,0,0,
+	"1.  NetDevice calls the function registered at Node::m_receiveCallback")])
+])
+])]).
+text('black',480,572,1,0,1,346,17,520,14,3,0,0,0,0,2,346,17,0,0,"",0,0,0,0,586,'',[
+minilines(346,17,0,0,0,0,0,[
+mini_line(346,14,3,0,0,0,[
+str_block(0,346,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,346,14,3,0,0,0,0,0,0,0,
+	"2.  This is typically the Node::ReceiveFromDevice() function")])
+])
+])]).
+text('black',479,509,3,0,1,460,51,524,14,3,0,0,0,0,2,460,51,0,0,"",0,0,0,0,523,'',[
+minilines(460,51,0,0,0,0,0,[
+mini_line(426,14,3,0,0,0,[
+str_block(0,426,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,426,14,3,0,-1,0,0,0,0,0,
+	"3.  Node::ReceiveFromDevice stores a set of callbacks (protocol handlers)")])
+]),
+mini_line(460,14,3,0,0,0,[
+str_block(0,460,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,460,14,3,0,-1,0,0,0,0,0,
+	" that are looked up based on protocol number and device.  In this case, the lookup")])
+]),
+mini_line(300,14,3,0,0,0,[
+str_block(0,300,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,300,14,3,0,-1,0,0,0,0,0,
+	"will result in Ipv4L3Protocol::Receive() being called.")])
+])
+])]).
+text('black',480,425,4,0,1,499,68,531,14,3,0,0,0,0,2,499,68,0,0,"",0,0,0,0,439,'',[
+minilines(499,68,0,0,0,0,0,[
+mini_line(475,14,3,0,0,0,[
+str_block(0,475,14,3,0,-2,0,0,0,[
+str_seg('black','Times-Roman',0,80640,475,14,3,0,-2,0,0,0,0,0,
+	"4.  Ipv4L3Protocol removes the IP header, checks checksum (if implemented), and ")])
+]),
+mini_line(467,14,3,0,0,0,[
+str_block(0,467,14,3,0,-2,0,0,0,[
+str_seg('black','Times-Roman',0,80640,467,14,3,0,-2,0,0,0,0,0,
+	"either Forwards the packet or calls ForwardUp().  ForwardUp() then looks up the ")])
+]),
+mini_line(499,14,3,0,0,0,[
+str_block(0,499,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,499,14,3,0,-1,0,0,0,0,0,
+	"IP protocol number in an IPv4L4Demux to obtain a pointer to an Ipv4L4Protocol object,")])
+]),
+mini_line(191,14,3,0,0,0,[
+str_block(0,191,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,191,14,3,0,-1,0,0,0,0,0,
+	"and calls the  ::Receive() method.")])
+])
+])]).
+text('black',281,548,1,0,1,140,17,541,14,3,2,0,0,0,2,140,17,0,0,"",0,0,0,0,562,'',[
+minilines(140,17,0,0,0,0,0,[
+mini_line(140,14,3,0,0,0,[
+str_block(0,140,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,140,14,3,0,-1,0,0,0,0,0,
+	"Node::ProtocolHandlers")])
+])
+])]).
+rcbox('black','',261,541,398,574,0,1,1,2,16,542,0,0,0,0,'1',0,[
+]).
+poly('black','',2,[
+	236,596,327,576],1,1,1,548,0,0,2,0,0,0,0,'1',0,0,
+    "0","",[
+    0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+text('black',272,590,1,0,1,112,17,550,14,3,0,0,0,0,2,112,17,0,0,"",0,0,0,0,604,'',[
+minilines(112,17,0,0,0,0,0,[
+mini_line(112,14,3,0,0,0,[
+str_block(0,112,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,112,14,3,0,0,0,0,0,0,0,
+	"m_receiveCallback")])
+])
+])]).
+poly('black','',2,[
+	306,541,202,460],1,1,1,555,0,0,0,0,0,0,0,'1',0,0,
+    "0","",[
+    0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+poly('black','',2,[
+	280,447,367,423],3,1,1,566,0,0,3,0,0,0,0,'1',0,0,
+    "0","",[
+    0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+text('black',185,499,1,0,1,65,17,575,14,3,0,0,0,0,2,65,17,0,0,"",0,0,0,0,513,'',[
+minilines(65,17,0,0,0,0,0,[
+mini_line(65,14,3,0,0,0,[
+str_block(0,65,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,65,14,3,0,-1,0,0,0,0,0,
+	"::Receive()")])
+])
+])]).
+text('black',315,438,1,0,1,135,17,585,14,3,0,0,0,0,2,135,17,0,0,"",0,0,0,0,452,'',[
+minilines(135,17,0,0,0,0,0,[
+mini_line(135,14,3,0,0,0,[
+str_block(0,135,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,135,14,3,0,-1,0,0,0,0,0,
+	"::GetProtocol(protocol)")])
+])
+])]).
+poly('black','',2,[
+	201,426,201,366],1,1,1,593,0,0,0,0,0,0,0,'1',0,0,
+    "0","",[
+    0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+text('black',211,390,1,0,1,65,17,597,14,3,0,0,0,0,2,65,17,0,0,"",0,0,0,0,404,'',[
+minilines(65,17,0,0,0,0,0,[
+mini_line(65,14,3,0,0,0,[
+str_block(0,65,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,65,14,3,0,-1,0,0,0,0,0,
+	"::Receive()")])
+])
+])]).
+text('black',480,291,6,0,1,438,102,612,14,3,0,0,0,0,2,438,102,0,0,"",0,0,0,0,305,'',[
+minilines(438,102,0,0,0,0,0,[
+mini_line(293,14,3,0,0,0,[
+str_block(0,293,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,293,14,3,0,0,0,0,0,0,0,
+	"5.  UdpL4Protocol is where the socket-independent")])
+]),
+mini_line(428,14,3,0,0,0,[
+str_block(0,428,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,428,14,3,0,0,0,0,0,0,0,
+	"protocol logic for UDP is implemented.  The Receive() method removes the")])
+]),
+mini_line(420,14,3,0,0,0,[
+str_block(0,420,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,420,14,3,0,0,0,0,0,0,0,
+	"UDP header and looks up the per-flow context state, which is one or more")])
+]),
+mini_line(438,14,3,0,0,0,[
+str_block(0,438,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,438,14,3,0,-1,0,0,0,0,0,
+	"Ipv4EndPoint objects stored in an Ipv4EndPointDemux (indexed by src addr,")])
+]),
+mini_line(405,14,3,0,0,0,[
+str_block(0,405,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,405,14,3,0,-1,0,0,0,0,0,
+	"src port, dest addr, dest port).  It then calls Ipv4EndPoint::ForwardUp()")])
+]),
+mini_line(66,14,3,0,0,0,[
+str_block(0,66,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,66,14,3,0,-1,0,0,0,0,0,
+	"when done.")])
+])
+])]).
+poly('black','',2,[
+	201,331,201,271],1,1,1,619,0,0,0,0,0,0,0,'1',0,0,
+    "0","",[
+    0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+text('black',211,295,1,0,1,85,17,620,14,3,0,0,0,0,2,85,17,0,0,"",0,0,0,0,309,'',[
+minilines(85,17,0,0,0,0,0,[
+mini_line(85,14,3,0,0,0,[
+str_block(0,85,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,85,14,3,0,-1,0,0,0,0,0,
+	"::ForwardUp()")])
+])
+])]).
+poly('black','',2,[
+	282,335,369,311],3,1,1,630,0,0,3,0,0,0,0,'1',0,0,
+    "0","",[
+    0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+text('black',317,326,1,0,1,62,17,631,14,3,0,0,0,0,2,62,17,0,0,"",0,0,0,0,340,'',[
+minilines(62,17,0,0,0,0,0,[
+mini_line(62,14,3,0,0,0,[
+str_block(0,62,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,62,14,3,0,-1,0,0,0,0,0,
+	"::Lookup()")])
+])
+])]).
+text('black',211,208,1,0,1,181,17,650,14,3,0,0,0,0,2,181,17,0,0,"",0,0,0,0,222,'',[
+minilines(181,17,0,0,0,0,0,[
+mini_line(181,14,3,0,0,0,[
+str_block(0,181,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,181,14,3,0,-1,0,0,0,0,0,
+	"(m_rxCallback)->ForwardUp()")])
+])
+])]).
+poly('black','',2,[
+	201,233,201,196],1,1,1,652,0,0,0,0,0,0,0,'1',0,0,
+    "0","",[
+    0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+text('black',211,138,1,0,1,144,17,656,14,3,0,0,0,0,2,144,17,0,0,"",0,0,0,0,152,'',[
+minilines(144,17,0,0,0,0,0,[
+mini_line(144,14,3,0,0,0,[
+str_block(0,144,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,144,14,3,0,-1,0,0,0,0,0,
+	"(m_rxCallback)->Recv()")])
+])
+])]).
+text('black',149,17,1,0,1,321,21,683,17,4,0,0,0,0,2,321,21,0,0,"",0,0,0,0,34,'',[
+minilines(321,21,0,0,0,0,0,[
+mini_line(321,17,4,0,0,0,[
+str_block(0,321,17,4,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,103680,321,17,4,0,0,0,0,0,0,0,
+	"Function/object trace for receiving a packet")])
+])
+])]).
+poly('black','',2,[
+	199,163,199,126],1,1,1,691,0,0,0,0,0,0,0,'1',0,0,
+    "0","",[
+    0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+group([
+text('black',311,280,1,0,1,120,17,484,14,3,0,0,0,0,2,120,17,0,0,"",0,0,0,0,294,'',[
+minilines(120,17,0,0,0,0,0,[
+mini_line(120,14,3,0,0,0,[
+str_block(0,120,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,120,14,3,0,0,0,0,0,0,0,
+	"Ipv4EndPointDemux")])
+])
+])]),
+polygon('black','',6,[
+	309,276,324,305,419,305,439,277,309,277,309,276],0,1,1,0,485,0,0,0,0,0,'1',0,
+    "00",[
+])
+],
+704,0,0,[
+]).
+text('black',480,190,3,0,1,363,51,708,14,3,0,0,0,0,2,363,51,0,0,"",0,0,0,0,204,'',[
+minilines(363,51,0,0,0,0,0,[
+mini_line(363,14,3,0,0,0,[
+str_block(0,363,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,363,14,3,0,-1,0,0,0,0,0,
+	"6.  Ipv4EndPoint has a callback where a Socket object is able to")])
+]),
+mini_line(304,14,3,0,0,0,[
+str_block(0,304,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,304,14,3,0,-1,0,0,0,0,0,
+	"register a receive method.  Here, this callback calls to")])
+]),
+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,
+	"UdpSocketImpl::ForwardUp()")])
+])
+])]).
+text('black',480,106,3,0,1,446,51,712,14,3,0,0,0,0,2,446,51,0,0,"",0,0,0,0,120,'',[
+minilines(446,51,0,0,0,0,0,[
+mini_line(407,14,3,0,0,0,[
+str_block(0,407,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,407,14,3,0,0,0,0,0,0,0,
+	"7.  UdpSocketImpl itself calls the Recv() callback set by the Application")])
+]),
+mini_line(402,14,3,0,0,0,[
+str_block(0,402,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,402,14,3,0,0,0,0,0,0,0,
+	"when data is ready to be read.  The application can then call the socket")])
+]),
+mini_line(446,14,3,0,0,0,[
+str_block(0,446,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,446,14,3,0,-1,0,0,0,0,0,
+	"Recv() or RecvFrom() methods to read data (or dummy data) from the socket.")])
+])
+])]).
+group([
+text('black',308,393,1,0,1,96,17,772,14,3,0,0,0,0,2,96,17,0,0,"",0,0,0,0,407,'',[
+minilines(96,17,0,0,0,0,0,[
+mini_line(96,14,3,0,0,0,[
+str_block(0,96,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,96,14,3,0,0,0,0,0,0,0,
+	"    Ipv4L4Demux")])
+])
+])]),
+polygon('black','',6,[
+	306,389,321,418,416,418,436,390,306,390,306,389],0,1,1,0,771,0,0,0,0,0,'1',0,
+    "00",[
+])
+],
+770,0,0,[
+]).
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/figures/internet-node-send.obj	Mon Jun 30 22:41:22 2008 -0700
@@ -0,0 +1,352 @@
+%TGIF 4.1.43-QPL
+state(0,37,100.000,83,0,0,16,0,9,1,1,0,0,3,2,1,0,'Times-Roman',0,80640,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,'').
+group([
+rcbox('black','',158,451,238,499,2,1,1,0,16,125,0,0,0,0,'1',0,[
+]),
+text('black',158,470,1,0,1,72,18,124,13,5,0,0,0,0,2,72,18,0,0,"",0,0,0,0,483,'',[
+minilines(72,18,0,0,0,0,0,[
+mini_line(72,13,5,0,0,0,[
+str_block(0,72,13,5,0,0,0,0,0,[
+str_seg('black','Courier',0,80640,72,13,5,0,0,0,0,0,0,0,
+	"NetDevice")])
+])
+])])
+],
+141,0,0,[
+]).
+group([
+rcbox('black','',147,77,255,125,2,1,1,0,16,354,0,0,0,0,'1',0,[
+]),
+text('black',163,96,1,0,1,88,18,353,13,5,0,0,0,0,2,88,18,0,0,"",0,0,0,0,109,'',[
+minilines(88,18,0,0,0,0,0,[
+mini_line(88,13,5,0,0,0,[
+str_block(0,88,13,5,0,0,0,0,0,[
+str_seg('black','Courier',0,80640,88,13,5,0,0,0,0,0,0,0,
+	"Application")])
+])
+])])
+],
+352,0,0,[
+]).
+text('black',202,172,1,1,1,90,17,473,14,3,2,0,0,0,2,90,17,0,0,"",0,0,0,0,186,'',[
+minilines(90,17,0,0,1,0,0,[
+mini_line(90,14,3,0,0,0,[
+str_block(0,90,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,90,14,3,0,0,0,0,0,0,0,
+	"UdpSocketImpl")])
+])
+])]).
+rcbox('black','',132,165,269,198,0,1,1,0,16,474,0,0,0,0,'1',0,[
+]).
+text('black',202,241,1,1,1,88,17,475,14,3,2,0,0,0,2,88,17,0,0,"",0,0,0,0,255,'',[
+minilines(88,17,0,0,1,0,0,[
+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,
+	"UdpL4Protocol")])
+])
+])]).
+rcbox('black','',132,234,269,267,0,1,1,0,16,476,0,0,0,0,'1',0,[
+]).
+text('black',201,317,1,1,1,90,17,490,14,3,2,0,0,0,2,90,17,0,0,"",0,0,0,0,331,'',[
+minilines(90,17,0,0,1,0,0,[
+mini_line(90,14,3,0,0,0,[
+str_block(0,90,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,90,14,3,0,0,0,0,0,0,0,
+	"Ipv4L3Protocol")])
+])
+])]).
+rcbox('black','',131,310,268,343,0,1,1,0,16,491,0,0,0,0,'1',0,[
+]).
+text('black',540,56,1,0,1,180,17,496,14,3,0,0,0,0,2,180,17,0,0,"",0,0,0,0,70,'',[
+minilines(180,17,0,0,0,0,0,[
+mini_line(180,14,3,0,0,0,[
+str_block(0,180,14,3,0,-2,0,0,0,[
+str_seg('black','Times-Roman',0,80640,180,14,3,0,-2,1,0,0,0,0,
+	"Step in packet sending process:")])
+])
+])]).
+text('black',480,420,4,0,1,460,68,524,14,3,0,0,0,0,2,460,68,0,0,"",0,0,0,0,434,'',[
+minilines(460,68,0,0,0,0,0,[
+mini_line(457,14,3,0,0,0,[
+str_block(0,457,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,457,14,3,0,0,0,0,0,0,0,
+	"5.  Ipv4Interface is an abstract base class; here, we depict the ArpIpv4Interface")])
+]),
+mini_line(460,14,3,0,0,0,[
+str_block(0,460,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,460,14,3,0,-1,0,0,0,0,0,
+	"concrete class.  This object looks up the MAC address if Arp is supported on this")])
+]),
+mini_line(454,14,3,0,0,0,[
+str_block(0,454,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,454,14,3,0,0,0,0,0,0,0,
+	"NetDevice technology, and if there is a cache hit, it sends it to the NetDevice, or")])
+]),
+mini_line(197,14,3,0,0,0,[
+str_block(0,197,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,197,14,3,0,-1,0,0,0,0,0,
+	"else it first initiates an Arp request.")])
+])
+])]).
+text('black',479,354,3,0,1,476,51,531,14,3,0,0,0,0,2,476,51,0,0,"",0,0,0,0,368,'',[
+minilines(476,51,0,0,0,0,0,[
+mini_line(469,14,3,0,0,0,[
+str_block(0,469,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,469,14,3,0,0,0,0,0,0,0,
+	"4.  Ipv4L3Protocol adds the IP header, looks up a route, and sends the packet to an")])
+]),
+mini_line(476,14,3,0,0,0,[
+str_block(0,476,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,476,14,3,0,-1,0,0,0,0,0,
+	"appropriate Ipv4Interface instance.   In this example, the device is one that supports")])
+]),
+mini_line(322,14,3,0,0,0,[
+str_block(0,322,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,322,14,3,0,-1,0,0,0,0,0,
+	"Arp, so the packet is sent to an ArpIpv4Interface object.")])
+])
+])]).
+text('black',478,261,4,0,1,437,68,612,14,3,0,0,0,0,2,437,68,0,0,"",0,0,0,0,275,'',[
+minilines(437,68,0,0,0,0,0,[
+mini_line(293,14,3,0,0,0,[
+str_block(0,293,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,293,14,3,0,0,0,0,0,0,0,
+	"3.  UdpL4Protocol is where the socket-independent")])
+]),
+mini_line(387,14,3,0,0,0,[
+str_block(0,387,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,387,14,3,0,0,0,0,0,0,0,
+	"protocol logic for UDP is implemented.  The Send() method adds the")])
+]),
+mini_line(437,14,3,0,0,0,[
+str_block(0,437,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,437,14,3,0,-1,0,0,0,0,0,
+	"UDP header, initializes the checksum, and sends the packet to the Ipv4 layer.")])
+]),
+mini_line(431,14,3,0,0,0,[
+str_block(0,431,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,431,14,3,0,-1,0,0,0,0,0,
+	"Here, the Ipv4L3Protocol object is queried, and the Send() method is called.")])
+])
+])]).
+poly('black','',2,[
+	201,308,201,271],2,1,1,619,0,0,0,0,0,0,0,'1',0,0,
+    "0","",[
+    0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+text('black',208,278,1,0,1,47,17,620,14,3,0,0,0,0,2,47,17,0,0,"",0,0,0,0,292,'',[
+minilines(47,17,0,0,0,0,0,[
+mini_line(47,14,3,0,0,0,[
+str_block(0,47,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,47,14,3,0,-1,0,0,0,0,0,
+	"::Send()")])
+])
+])]).
+text('black',211,208,1,0,1,47,17,650,14,3,0,0,0,0,2,47,17,0,0,"",0,0,0,0,222,'',[
+minilines(47,17,0,0,0,0,0,[
+mini_line(47,14,3,0,0,0,[
+str_block(0,47,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,47,14,3,0,-1,0,0,0,0,0,
+	"::Send()")])
+])
+])]).
+poly('black','',2,[
+	201,233,201,196],2,1,1,652,0,0,0,0,0,0,0,'1',0,0,
+    "0","",[
+    0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+text('black',211,138,1,0,1,87,17,656,14,3,0,0,0,0,2,87,17,0,0,"",0,0,0,0,152,'',[
+minilines(87,17,0,0,0,0,0,[
+mini_line(87,14,3,0,0,0,[
+str_block(0,87,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,87,14,3,0,-1,0,0,0,0,0,
+	"Socket::Send()")])
+])
+])]).
+text('black',149,17,1,0,1,310,21,683,17,4,0,0,0,0,2,310,21,0,0,"",0,0,0,0,34,'',[
+minilines(310,21,0,0,0,0,0,[
+mini_line(310,17,4,0,0,0,[
+str_block(0,310,17,4,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,103680,310,17,4,0,0,0,0,0,0,0,
+	"Function/object trace for sending a packet")])
+])
+])]).
+poly('black','',2,[
+	199,163,199,126],2,1,1,691,0,0,0,0,0,0,0,'1',0,0,
+    "0","",[
+    0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+text('black',480,153,6,0,1,524,102,708,14,3,0,0,0,0,2,524,102,0,0,"",0,0,0,0,167,'',[
+minilines(524,102,0,0,0,0,0,[
+mini_line(399,14,3,0,0,0,[
+str_block(0,399,14,3,0,-2,0,0,0,[
+str_seg('black','Times-Roman',0,80640,399,14,3,0,-2,0,0,0,0,0,
+	"2.  Socket::Send() forwards to UdpSocketImpl::DoSend() and later to ")])
+]),
+mini_line(173,14,3,0,0,0,[
+str_block(0,173,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,173,14,3,0,-1,0,0,0,0,0,
+	"UdpSocketImpl::DoSendTo().")])
+]),
+mini_line(479,14,3,0,0,0,[
+str_block(0,479,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,479,14,3,0,-1,0,0,0,0,0,
+	"These functions set the proper source and destination addresses, handle socket calls")])
+]),
+mini_line(524,14,3,0,0,0,[
+str_block(0,524,14,3,0,-2,0,0,0,[
+str_seg('black','Times-Roman',0,80640,524,14,3,0,-2,0,0,0,0,0,
+	"such as bind() and connect() and then the UdpL4Protocol::Send() function is called.  As in a ")])
+]),
+mini_line(505,14,3,0,0,0,[
+str_block(0,505,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,505,14,3,0,-1,0,0,0,0,0,
+	"real implementation, the socket must query the Ipv4 layer to find the right source address")])
+]),
+mini_line(187,14,3,0,0,0,[
+str_block(0,187,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,187,14,3,0,-1,0,0,0,0,0,
+	"to match the destination address.")])
+])
+])]).
+text('black',480,106,2,0,1,434,34,712,14,3,0,0,0,0,2,434,34,0,0,"",0,0,0,0,120,'',[
+minilines(434,34,0,0,0,0,0,[
+mini_line(413,14,3,0,0,0,[
+str_block(0,413,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,413,14,3,0,-1,0,0,0,0,0,
+	"1.  The Application has previously created a socket (here, a UdpSocket).")])
+]),
+mini_line(434,14,3,0,0,0,[
+str_block(0,434,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,434,14,3,0,-1,0,0,0,0,0,
+	"It calls Socket::Send().  Either real data or dummy data is passed at the API.")])
+])
+])]).
+text('black',377,315,1,1,1,60,17,774,14,3,2,0,0,0,2,60,17,0,0,"",0,0,0,0,329,'',[
+minilines(60,17,0,0,1,0,0,[
+mini_line(60,14,3,0,0,0,[
+str_block(0,60,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,60,14,3,0,0,0,0,0,0,0,
+	"Ipv4Route")])
+])
+])]).
+rcbox('black','',307,308,444,341,0,1,1,0,16,775,0,0,0,0,'1',0,[
+]).
+poly('black','',2,[
+	267,325,304,325],3,1,1,787,0,0,3,0,0,0,0,'1',0,0,
+    "0","",[
+    0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+text('black',278,299,1,0,1,62,17,796,14,3,2,0,0,0,2,62,17,0,0,"",0,0,0,0,313,'',[
+minilines(62,17,0,0,0,0,0,[
+mini_line(62,14,3,0,0,0,[
+str_block(0,62,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,62,14,3,0,-1,0,0,0,0,0,
+	"::Lookup()")])
+])
+])]).
+text('black',200,385,1,1,1,102,17,803,14,3,2,0,0,0,2,102,17,0,0,"",0,0,0,0,399,'',[
+minilines(102,17,0,0,1,0,0,[
+mini_line(102,14,3,0,0,0,[
+str_block(0,102,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,102,14,3,0,0,0,0,0,0,0,
+	"ArpIpv4Interface")])
+])
+])]).
+rcbox('black','',130,378,267,411,0,1,1,0,16,804,0,0,0,0,'1',0,[
+]).
+poly('black','',2,[
+	199,380,199,343],2,1,1,810,0,0,0,0,0,0,0,'1',0,0,
+    "0","",[
+    0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+text('black',206,350,1,0,1,47,17,811,14,3,0,0,0,0,2,47,17,0,0,"",0,0,0,0,364,'',[
+minilines(47,17,0,0,0,0,0,[
+mini_line(47,14,3,0,0,0,[
+str_block(0,47,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,47,14,3,0,-1,0,0,0,0,0,
+	"::Send()")])
+])
+])]).
+text('black',378,388,1,1,1,71,17,817,14,3,2,0,0,0,2,71,17,0,0,"",0,0,0,0,402,'',[
+minilines(71,17,0,0,1,0,0,[
+mini_line(71,14,3,0,0,0,[
+str_block(0,71,14,3,0,0,0,0,0,[
+str_seg('black','Times-Roman',0,80640,71,14,3,0,0,0,0,0,0,0,
+	"ArpProtocol")])
+])
+])]).
+rcbox('black','',308,381,445,414,0,1,1,0,16,818,0,0,0,0,'1',0,[
+]).
+poly('black','',2,[
+	268,398,305,398],3,1,1,819,0,0,3,0,0,0,0,'1',0,0,
+    "0","",[
+    0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+text('black',279,372,1,0,1,62,17,820,14,3,2,0,0,0,2,62,17,0,0,"",0,0,0,0,386,'',[
+minilines(62,17,0,0,0,0,0,[
+mini_line(62,14,3,0,0,0,[
+str_block(0,62,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,62,14,3,0,-1,0,0,0,0,0,
+	"::Lookup()")])
+])
+])]).
+poly('black','',2,[
+	199,448,199,411],2,1,1,837,0,0,0,0,0,0,0,'1',0,0,
+    "0","",[
+    0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+text('black',206,418,1,0,1,47,17,838,14,3,0,0,0,0,2,47,17,0,0,"",0,0,0,0,432,'',[
+minilines(47,17,0,0,0,0,0,[
+mini_line(47,14,3,0,0,0,[
+str_block(0,47,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,47,14,3,0,-1,0,0,0,0,0,
+	"::Send()")])
+])
+])]).
+text('black',371,173,1,1,1,26,17,842,14,3,2,0,0,0,2,26,17,0,0,"",0,0,0,0,187,'',[
+minilines(26,17,0,0,1,0,0,[
+mini_line(26,14,3,0,0,0,[
+str_block(0,26,14,3,0,-1,0,0,0,[
+str_seg('black','Times-Roman',0,80640,26,14,3,0,-1,0,0,0,0,0,
+	"Ipv4")])
+])
+])]).
+rcbox('black','',301,166,438,199,0,1,1,0,16,843,0,0,0,0,'1',0,[
+]).
+text('black',272,157,1,0,1,148,17,844,14,3,2,0,0,0,2,148,17,0,0,"",0,0,0,0,171,'',[
+minilines(148,17,0,0,0,0,0,[
+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,
+	"::GetAddress(outgoing if)")])
+])
+])]).
+poly('black','',2,[
+	269,182,306,182],3,1,1,846,0,0,3,0,0,0,0,'1',0,0,
+    "0","",[
+    0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/figures/node.obj	Mon Jun 30 22:41:22 2008 -0700
@@ -0,0 +1,211 @@
+%TGIF 4.1.43-QPL
+state(0,37,100.000,0,0,0,16,0,9,1,1,0,0,3,2,1,0,'Times-Italic',2,80640,0,8,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,'').
+rcbox('black','',64,64,400,384,0,1,1,0,16,0,0,0,0,0,'1',0,[
+]).
+box('black','',280,432,555,464,0,1,1,17,0,0,0,0,0,'1',0,[
+]).
+text('black',384,435,1,0,1,56,18,18,13,5,0,0,0,0,2,56,18,0,0,"",0,0,0,0,448,'',[
+minilines(56,18,0,0,0,0,0,[
+mini_line(56,13,5,0,0,0,[
+str_block(0,56,13,5,0,-1,0,0,0,[
+str_seg('black','Courier-Bold',1,80640,56,13,5,0,-1,0,0,0,0,0,
+	"Channel")])
+])
+])]).
+text('black',76,42,1,0,1,208,18,108,13,5,2,0,0,0,2,208,18,0,0,"",0,0,0,0,55,'',[
+minilines(208,18,0,0,0,0,0,[
+mini_line(208,13,5,0,0,0,[
+str_block(0,208,13,5,0,0,0,0,0,[
+str_seg('black','Courier-Bold',1,80640,208,13,5,0,0,0,0,0,0,0,
+	"class Node : public Object")])
+])
+])]).
+group([
+rcbox('black','',112,304,192,352,2,1,1,0,16,134,0,0,0,0,'1',0,[
+]),
+text('black',112,323,1,0,1,72,18,135,13,5,0,0,0,0,2,72,18,0,0,"",0,0,0,0,336,'',[
+minilines(72,18,0,0,0,0,0,[
+mini_line(72,13,5,0,0,0,[
+str_block(0,72,13,5,0,0,0,0,0,[
+str_seg('black','Courier',0,80640,72,13,5,0,0,0,0,0,0,0,
+	"NetDevice")])
+])
+])])
+],
+138,0,0,[
+]).
+group([
+rcbox('black','',266,304,346,352,2,1,1,0,16,125,0,0,0,0,'1',0,[
+]),
+text('black',266,323,1,0,1,72,18,124,13,5,0,0,0,0,2,72,18,0,0,"",0,0,0,0,336,'',[
+minilines(72,18,0,0,0,0,0,[
+mini_line(72,13,5,0,0,0,[
+str_block(0,72,13,5,0,0,0,0,0,[
+str_seg('black','Courier',0,80640,72,13,5,0,0,0,0,0,0,0,
+	"NetDevice")])
+])
+])])
+],
+141,0,0,[
+]).
+poly('black','',2,[
+	304,351,304,430],3,1,1,167,0,2,0,0,0,0,0,'1',0,0,
+    "0","",[
+    0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+text('black',219,304,1,0,1,24,37,177,30,7,2,0,0,0,2,24,37,0,0,"",0,0,0,0,334,'',[
+minilines(24,37,0,0,0,0,0,[
+mini_line(24,30,7,0,0,0,[
+str_block(0,24,30,7,0,-2,0,0,0,[
+str_seg('black','Times-Bold',1,195840,24,30,7,0,-2,0,0,0,0,0,
+	"...")])
+])
+])]).
+text('black',220,98,1,0,1,24,37,182,30,7,2,0,0,0,2,24,37,0,0,"",0,0,0,0,128,'',[
+minilines(24,37,0,0,0,0,0,[
+mini_line(24,30,7,0,0,0,[
+str_block(0,24,30,7,0,-2,0,0,0,[
+str_seg('black','Times-Bold',1,195840,24,30,7,0,-2,0,0,0,0,0,
+	"...")])
+])
+])]).
+text('black',420,116,2,0,1,136,36,183,13,5,2,0,0,0,2,136,36,0,0,"",0,0,0,0,129,'',[
+minilines(136,36,0,0,0,0,0,[
+mini_line(136,13,5,0,0,0,[
+str_block(0,136,13,5,0,0,0,0,0,[
+str_seg('black','Courier-Bold',1,80640,136,13,5,0,0,0,0,0,0,0,
+	"Unix-like C-based")])
+]),
+mini_line(80,13,5,0,0,0,[
+str_block(0,80,13,5,0,-1,0,0,0,[
+str_seg('black','Courier-Bold',1,80640,80,13,5,0,-1,0,0,0,0,0,
+	"socket API")])
+])
+])]).
+text('black',414,212,3,0,1,232,54,198,13,5,2,0,0,0,2,232,54,0,0,"",0,0,0,0,225,'',[
+minilines(232,54,0,0,0,0,0,[
+mini_line(112,13,5,0,0,0,[
+str_block(0,112,13,5,0,0,0,0,0,[
+str_seg('black','Courier-Bold',1,80640,112,13,5,0,0,0,0,0,0,0,
+	"Callback-based")])
+]),
+mini_line(176,13,5,0,0,0,[
+str_block(0,176,13,5,0,0,0,0,0,[
+str_seg('black','Courier-Bold',1,80640,176,13,5,0,0,0,0,0,0,0,
+	"protocol demultiplexer")])
+]),
+mini_line(232,13,5,0,0,0,[
+str_block(0,8,13,5,0,-1,0,0,0,[
+str_seg('black','Courier-Bold',1,80640,8,13,5,0,-1,0,0,0,0,0,
+	"(")]),
+str_block(0,216,13,3,0,-2,0,0,0,[
+str_seg('black','Courier-Oblique',2,80640,216,13,3,0,-2,0,0,0,0,0,
+	"list of ProtocolHandlers")]),
+str_block(0,8,13,5,0,-2,0,0,0,[
+str_seg('black','Courier-Bold',1,80640,8,13,5,0,-2,0,0,0,0,0,
+	")")])
+])
+])]).
+poly('black','',2,[
+	410,231,222,259],1,1,1,200,0,2,2,0,0,0,0,'1',0,0,
+    "0","",[
+    0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+box('black','',56,401,229,433,0,1,1,250,0,0,0,0,0,'1',0,[
+]).
+text('black',119,409,1,0,1,56,18,251,13,5,0,0,0,0,2,56,18,0,0,"",0,0,0,0,422,'',[
+minilines(56,18,0,0,0,0,0,[
+mini_line(56,13,5,0,0,0,[
+str_block(0,56,13,5,0,-1,0,0,0,[
+str_seg('black','Courier-Bold',1,80640,56,13,5,0,-1,0,0,0,0,0,
+	"Channel")])
+])
+])]).
+poly('black','',2,[
+	154,353,154,400],3,1,1,254,0,2,0,0,0,0,0,'1',0,0,
+    "0","",[
+    0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
+]).
+group([
+rcbox('black','',98,96,206,144,2,1,1,0,16,1,0,0,0,0,'1',0,[
+]),
+text('black',114,115,1,0,1,88,18,2,13,5,0,0,0,0,2,88,18,0,0,"",0,0,0,0,128,'',[
+minilines(88,18,0,0,0,0,0,[
+mini_line(88,13,5,0,0,0,[
+str_block(0,88,13,5,0,0,0,0,0,[
+str_seg('black','Courier',0,80640,88,13,5,0,0,0,0,0,0,0,
+	"Application")])
+])
+])])
+],
+348,0,0,[
+]).
+group([
+rcbox('black','',257,96,365,144,2,1,1,0,16,354,0,0,0,0,'1',0,[
+]),
+text('black',273,115,1,0,1,88,18,353,13,5,0,0,0,0,2,88,18,0,0,"",0,0,0,0,128,'',[
+minilines(88,18,0,0,0,0,0,[
+mini_line(88,13,5,0,0,0,[
+str_block(0,88,13,5,0,0,0,0,0,[
+str_seg('black','Courier',0,80640,88,13,5,0,0,0,0,0,0,0,
+	"Application")])
+])
+])])
+],
+352,0,0,[
+]).
+text('black',155,73,1,0,1,110,18,426,14,4,2,0,0,0,2,110,18,0,0,"",0,0,0,0,87,'',[
+minilines(110,18,0,0,0,0,0,[
+mini_line(110,14,4,0,0,0,[
+str_block(0,110,14,4,0,-1,0,0,0,[
+str_seg('black','Times-Italic',2,80640,110,14,4,0,-1,0,0,0,0,0,
+	"list of Applications")])
+])
+])]).
+text('black',161,357,1,0,1,106,18,443,14,4,2,0,0,0,2,106,18,0,0,"",0,0,0,0,371,'',[
+minilines(106,18,0,0,0,0,0,[
+mini_line(106,14,4,0,0,0,[
+str_block(0,106,14,4,0,-1,0,0,0,[
+str_seg('black','Times-Italic',2,80640,106,14,4,0,-1,0,0,0,0,0,
+	"list of NetDevices")])
+])
+])]).
+text('black',79,194,2,0,1,55,36,482,14,4,2,0,0,0,2,55,36,0,0,"",0,0,0,0,208,'',[
+minilines(55,36,0,0,0,0,0,[
+mini_line(53,14,4,0,0,0,[
+str_block(0,53,14,4,0,0,0,0,0,[
+str_seg('black','Times-Italic',2,80640,53,14,4,0,0,0,0,0,0,0,
+	"unique id")])
+]),
+mini_line(55,14,4,0,0,0,[
+str_block(0,55,14,4,0,0,0,0,0,[
+str_seg('black','Times-Italic',2,80640,55,14,4,0,0,0,0,0,0,0,
+	"system id")])
+])
+])]).
+polygon('black','',7,[
+	158,271,305,271,288,291,173,291,159,273,160,273,158,271],2,1,1,0,493,8,0,0,0,0,'1',0,
+    "00",[
+]).
--- a/doc/manual/manual.texi	Mon Jun 30 14:17:19 2008 -0700
+++ b/doc/manual/manual.texi	Mon Jun 30 22:41:22 2008 -0700
@@ -83,6 +83,7 @@
 * Attributes::
 * Packets::
 * Sockets APIs::
+* Node and Internet Stack::
 * Routing overview::
 * Troubleshooting
 @end menu
@@ -92,6 +93,7 @@
 @include attributes.texi
 @include packets.texi
 @include sockets.texi
+@include node.texi
 @c @include output.texi
 @include routing.texi
 @c @include other.texi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/node.texi	Mon Jun 30 22:41:22 2008 -0700
@@ -0,0 +1,358 @@
+@node Node and Internet Stack
+@chapter Node and Internet Stack
+@anchor{chap:Node}
+
+This chapter describes how ns-3 nodes are put together, and provides
+a walk-through of how packets traverse an internet-based Node.
+
+@float Figure,fig:node
+@caption{High-level node architecture.}
+@image{figures/node,5in}
+@end float
+
+In ns-3, nodes are instances of @code{class Node}.  This class
+may be subclassed, but instead, the conceptual model is that 
+we @emph{aggregate} or insert objects to it rather than define 
+subclasses.
+
+One might think of a bare ns-3 node as a shell of a computer,
+to which one may add NetDevices (cards) and other innards including
+the protocols and applications.  @ref{fig:node} illustrates
+that Node objects contain a list of Applications (initially,
+the list is empty), a list of NetDevices (initially, the list
+is empty), a unique integer ID, and a system ID (for
+distributed simulation).
+
+The design tries to avoid putting too many dependencies on the
+base class Node, Application, or NetDevice for the following:
+@itemize @bullet
+@item IP version, or whether IP is at all even used in the Node.
+@item implementation details of the IP stack 
+@end itemize 
+
+From a software perspective, the lower interface of applications
+corresponds to the C-based sockets API.  The upper interface
+of NetDevice objects corresponds to the device independent
+sublayer of the Linux stack.  Everything in between can be
+aggregated and plumbed together as needed.
+
+Let's look more closely at the protocol demultiplexer.  We want
+incoming frames at layer-2 to be delivered to the right layer-3
+protocol such as Ipv4.  The
+function of this demultiplexer is to register callbacks for
+receiving packets.  The callbacks are indexed based on the 
+@uref{http://en.wikipedia.org/wiki/EtherType,,EtherType}
+in the layer-2 frame.   
+
+Many different types of higher-layer protocols may be 
+connected to the NetDevice, such as IPv4, IPv6, ARP,
+MPLS, IEEE 802.1x, and packet sockets.  Therefore, the
+use of a callback-based demultiplexer avoids the need to
+use a common base class for all of these protocols, which
+is problematic because of the different types of objects
+(including packet sockets) expected to be registered there.
+
+Each NetDevice delivers packets to a callback with the following
+signature:
+@verbatim
+  /**
+   * \param device a pointer to the net device which is calling this callback
+   * \param packet the packet received
+   * \param protocol the 16 bit protocol number associated with this packet.
+   *        This protocol number is expected to be the same protocol number
+   *        given to the Send method by the user on the sender side.
+   * \param address the address of the sender
+   * \returns true if the callback could handle the packet successfully, 
+   *        false otherwise.
+   */
+  typedef Callback<bool, Ptr<NetDevice>, Ptr<Packet>, uint16_t,
+    const Address &> ReceiveCallback;
+@end verbatim
+
+There is a function in class Node that matches that signature:
+@verbatim
+private:
+  bool ReceiveFromDevice (Ptr<NetDevice> device, Ptr<Packet>,
+                          uint16_t protocol, const Address &from);
+@end verbatim
+
+However, users do not need to access this function directly.  Instead,
+when users call @code{uint32_t AddDevice (Ptr<NetDevice> device)}, 
+the implementation of this function sets the callback (and the
+function returns the ifIndex of the NetDevice on that Node).
+
+But what does the ReceiveFromDevice function do?  Here, it looks
+up another callback, in its list of callbacks, corresponding to the
+matching EtherType.  This callback is called a ProtocolHandler, and
+is specified as follows:
+@verbatim
+  typedef Callback<void, Ptr<NetDevice>, Ptr<Packet>, uint16_t,
+    const Address &> ProtocolHandler;
+@end verbatim
+
+Upper-layer protocols or objects are expected to provide such a function.
+and register it with the list of ProtocolHandlers by calling
+@code{Node::RegisterProtocolHandler ();}
+For instance, if Ipv4 is aggregated to a Node, then the Ipv4 receive
+function can be registered with the protocol handler by calling:
+@verbatim
+  RegisterProtocolHandler (
+    MakeCallback (&Ipv4L3Protocol::Receive, ipv4), 
+    Ipv4L3Protocol::PROT_NUMBER, 0);
+@end verbatim
+and likewise for Ipv6, Arp, etc.
+
+@section NodeList
+
+Every Node created is automatically added to the ns-3 @code{NodeList}.
+The NodeList class provides an @code{Add()} method and C++ iterators
+to allow one to walk the node list or fetch a Node pointer by
+its integer identifier.
+
+@section Internet stack aggregation
+
+The above @code{class Node} is not very useful as-is; other objects
+must be aggregated to it to provide useful node functionality.
+
+The ns-3 source code directory @code{src/internet-stack} provides
+implmentation of TCP/IPv4-related components.  These include IPv4,
+ARP, UDP, TCP, and other related protocols.
+
+Internet Nodes are not subclasses of class Node; they are simply Nodes 
+that have had a bunch of IPv4-related
+objects aggregated to them.  They can be put together by hand, or
+via a helper function @code{AddInternetStack ()} which does the 
+following:
+@verbatim
+void AddInternetStack (Ptr<Node> node)
+{
+  // Create layer-3 protocols 
+  Ptr<Ipv4L3Protocol> ipv4 = CreateObject<Ipv4L3Protocol> ();
+  Ptr<ArpL3Protocol> arp = CreateObject<ArpL3Protocol> ();
+  ipv4->SetNode (node);
+  arp->SetNode (node);
+
+  // Create an L4 demux 
+  Ptr<Ipv4L4Demux> ipv4L4Demux = CreateObject<Ipv4L4Demux> ();
+
+  // Create transport protocols and insert them into the demux
+  Ptr<UdpL4Protocol> udp = CreateObject<UdpL4Protocol> ();
+  Ptr<TcpL4Protocol> tcp = CreateObject<TcpL4Protocol> ();
+  
+  ipv4L4Demux->SetNode (node);
+  udp->SetNode (node);
+  tcp->SetNode (node);
+  
+  ipv4L4Demux->Insert (udp);
+  ipv4L4Demux->Insert (tcp);
+  
+  // Add factories for instantiating transport protocol sockets
+  Ptr<UdpSocketFactoryImpl> udpFactory = CreateObject<UdpSocketFactoryImpl> ();
+  Ptr<TcpSocketFactoryImpl> tcpFactory = CreateObject<TcpSocketFactoryImpl> ();
+  Ptr<Ipv4Impl> ipv4Impl = CreateObject<Ipv4Impl> ();
+  
+  udpFactory->SetUdp (udp);
+  tcpFactory->SetTcp (tcp);
+  ipv4Impl->SetIpv4 (ipv4);
+  
+  // Aggregate all of these new objects to the node
+  node->AggregateObject (ipv4);
+  node->AggregateObject (arp);
+  node->AggregateObject (ipv4Impl);
+  node->AggregateObject (udpFactory);
+  node->AggregateObject (tcpFactory);
+  node->AggregateObject (ipv4L4Demux);
+}
+@end verbatim
+
+@subsection Internet Node structure
+
+The Internet Node (an ns-3 Node augmented by aggregation to have one or more
+IP stacks) has the following internal structure.
+
+@subsubsection Layer-3 protocols
+At the lowest layer, sitting above the NetDevices, are the "layer 3" 
+protocols, including IPv4, IPv6, and ARP.  These protocols provide 
+the following key methods and data members:
+
+@verbatim
+class Ipv4L3Protocol : public Object
+{
+public: 
+  // Add an Ipv4 interface corresponding to the provided NetDevice
+  uint32_t AddInterface (Ptr<NetDevice> device);
+
+  // Receive function that can be bound to a callback, for receiving
+  // packets up the stack
+  void Receive( Ptr<NetDevice> device, Ptr<Packet> p, uint16_t protocol, 
+    const Address &from);
+
+  // Higher-level layers call this method to send a packet
+  // down the stack to the MAC and PHY layers
+  // 
+  void Send (Ptr<Packet> packet, Ipv4Address source,
+             Ipv4Address destination, uint8_t protocol);
+
+private:
+  Ipv4InterfaceList m_interfaces;
+
+  // Protocol handlers
+}
+@end verbatim
+There are many more functions (such as @code{Forward ()}) but we will
+focus on the above four items from an architectural perspective.
+
+First, note that the @code{Receive ()} function has a matching signature
+to the ReceiveCallback in the @code{class Node}.  This function pointer
+is inserted into the the Node's protocol handler when 
+@code{AddInterface ()} is called.  The actual registration is done
+with a statement such as:
+follows:
+@verbatim
+ RegisterProtocolHandler ( MakeCallback (&Ipv4Protocol::Receive, ipv4),
+    Ipv4L3Protocol::PROT_NUMBER, 0);
+@end verbatim
+
+The Ipv4L3Protocol object is aggregated to the Node; there is only one
+such Ipv4L3Protocol object.  Higher-layer protocols that have a packet
+to send down to the Ipv4L3Protocol object can call 
+@code{GetObject<Ipv4L3Protocol> ()} to obtain a pointer, as follows:
+@verbatim
+  Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
+  if (ipv4 != 0)
+    {
+      ipv4->Send (packet, saddr, daddr, PROT_NUMBER);
+    }
+@end verbatim
+
+This class nicely demonstrates two techniques we exploit in
+ns-3 to bind objects together:  callbacks, and object aggregation.
+
+Once IPv4 has determined that a packet is for the local node, it 
+forwards it up the stack.  This is done with the following function:
+
+@verbatim
+void
+Ipv4L3Protocol::ForwardUp (Ptr<Packet> p, Ipv4Header const&ip,
+                           Ptr<Ipv4Interface> incomingInterface)
+{
+  NS_LOG_FUNCTION (this << p << &ip);
+
+  Ptr<Ipv4L4Demux> demux = m_node->GetObject<Ipv4L4Demux> ();
+  Ptr<Ipv4L4Protocol> protocol = demux->GetProtocol (ip.GetProtocol ());
+  protocol->Receive (p, ip.GetSource (), ip.GetDestination (), incomingInterface);
+}
+@end verbatim
+
+The first step is to find the aggregated Ipv4L4Demux object.  Then, this
+object is consulted to look up the right Ipv4L4Protocol, based on IP protocol
+number.  For instance, TCP is registered in the demux as protocol number 6.
+Finally, the @code{Receive()} function on the Ipv4L4Protocol (such as
+@code{TcpL4Protocol::Receive} is called.
+
+We have not yet introduced the class Ipv4Interface.  Basically,
+each NetDevice is paired with an IPv4 representation of such device.
+In Linux, this @code{class Ipv4Interface} roughly corresponds to
+the @code{struct in_device}; the main purpose is to provide 
+address-family specific information (addresses) about an interface.
+
+@subsubsection Layer-4 protocols and sockets
+
+We next describe how the transport protocols, sockets, and applications
+tie together.  In summary, each transport protocol implementation is
+a socket factory.  An application that needs a new socket 
+
+For instance, to create a UDP socket, an application would use a code
+snippet such as the following:
+@verbatim
+      Ptr<Udp> udpSocketFactory = GetNode ()->GetObject<Udp> ();
+      Ptr<Socket> m_socket = socketFactory->CreateSocket ();
+      m_socket->Bind (m_local_address);
+      ...
+@end verbatim 
+The above will query the node to get a pointer to its UDP socket
+factory, will create one such socket, and will use the socket with
+an API similar to the C-based sockets API, such as @code{Connect ()}
+and @code{Send ()}.  See the chapter on ns-3 sockets for more information.  
+
+We have described so far a socket factory (e.g. @code{class Udp}) and
+a socket, which may be specialized (e.g., @code{class UdpSocket}).
+There are a few more key objects that relate to the specialized
+task of demultiplexing a packet to one or more receiving sockets.
+The key object in this task is @code{class Ipv4EndPointDemux}.
+This demultiplexer stores objects of @code{class Ipv4EndPoint}.
+This class holds the addressing/port tuple (local port, local address, 
+destination port, destination address) associated with the socket, 
+and a receive callback.  This receive callback has a receive
+function registered by the socket.  The @code{Lookup ()} function to
+Ipv4EndPointDemux returns a list of Ipv4EndPoint objects (there may
+be a list since more than one socket may match the packet).  The
+layer-4 protocol copies the packet to each Ipv4EndPoint and calls
+its @code{ForwardUp ()} method, which then calls the @code{Receive ()}
+function registered by the socket.
+
+An issue that arises when working with the sockets API on real
+systems is the need to manage the reading from a socket, using 
+some type of I/O (e.g., blocking, non-blocking, asynchronous, ...).
+ns-3 implements an asynchronous model for socket I/O; the application
+sets a callback to be notified of received data ready to be read, and the 
+callback is invoked by the transport protocol when data is available.
+This callback is specified as follows:
+@verbatim
+  void Socket::SetRecvCallback (Callback<void, Ptr<Socket>, 
+    Ptr<Packet>, const Address&> receivedData);
+@end verbatim
+The data being received is conveyed in the Packet data buffer.  An example
+usage is in @code{class PacketSink}:
+@verbatim
+  m_socket->SetRecvCallback (MakeCallback(&PacketSink::HandleRead, this));
+@end verbatim
+
+To summarize, internally, the UDP implementation is organized as follows:
+@itemize @bullet
+@item a @code{UdpImpl} class that implements the Udp socket factory
+functionality
+@item a @code{UdpL4Protocol} class that implements the protocol logic
+that is socket-independent 
+@item a @code{UdpSocketImpl} class that implements socket-specific aspects
+of UDP
+@item a class called @code{Ipv4EndPoint} that stores the
+addressing tuple (local port, local address, destination port, destination
+address) associated with the socket, and a receive callback for the socket.
+@end itemize
+
+@subsection Internet Node interfaces
+
+Many of the implementation details, or internal objects themselves, 
+of Internet Node objects are not exposed at the simulator public
+API.  This allows for different implementations; for instance, 
+replacing the native ns-3 models with ported TCP/IP stack code. 
+ 
+The C++ public APIs of all of these objects is found in the
+@code{src/node} directory, including principally:
+@itemize @bullet
+@item @code{socket.h}
+@item @code{tcp.h}
+@item @code{udp.h}
+@item @code{ipv4.h}
+@end itemize 
+These are typically base class objects that implement the default
+values used in the implementation, implement access methods to get/set
+state variables, host attributes, and implement publicly-available methods 
+exposed to clients such as @code{CreateSocket}.
+
+@subsection Example path of a packet
+
+These two figures show an example stack trace of how packets flow
+through the Internet Node objects.
+
+@float Figure,fig:internet-node-send
+@caption{Send path of a packet.}
+@image{figures/internet-node-send,5in}
+@end float
+
+@float Figure,fig:internet-node-recv
+@caption{Receive path of a packet.}
+@image{figures/internet-node-recv,5in}
+@end float
+