lan.tex
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:23k
源码类别:

通讯编程

开发平台:

Visual C++

  1. %documentstyle[11pt,fullpage]{article}
  2. %setlength{parindent}{0 in}
  3. %setlength{parskip}{.1in}
  4. %setlength{topmargin}{-0.5in}
  5. %setlength{textheight}{8.5in}
  6. %begin{document}
  7. %
  8. % personal commentary:
  9. %        DRAFT DRAFT DRAFT
  10. %        - GNGUYEN
  11. %
  12. chapter{Local Area Networks}
  13. label{chap:lan}
  14. The characteristics of the wireless and local area networks (LAN) are
  15. inherently different from those of point-to-point links.  A network
  16. consisting of multiple point-to-point links cannot capture the sharing
  17. and contention properties of a LAN.  To simulate these properties, we
  18. created a new type of a Node, called code{LanNode}.  The OTcl
  19. configurations and interfaces for code{LanNode} reside in the following
  20. two files in the main ns directory:
  21. begin{verbatim}
  22.         tcl/lan/vlan.tcl
  23.         tcl/lan/ns-ll.tcl
  24.         tcl/lan/ns-mac.tcl
  25. end{verbatim}
  26. section{Tcl configuration}
  27. label{sec:lan_tcl}
  28. The interface for creating and configuring a LAN slightly differs from
  29. those of point-to-point link.  At the top level, the OTcl class
  30. code{Simulator} exports a new method called code{make-lan}.  The
  31. parameters to this method are similar to the method code{duplex-link},
  32. except that code{make-lan} only accepts a list of nodes as a single
  33. parameter instead of 2 parameters as in code{duplex-link}:
  34. begin{verbatim}
  35. Simulator instproc make-lan {nodes bw delay lltype ifqtype mactype chantype}
  36. end{verbatim}
  37. The optional parameters to code{make-lan} specify the type of objects
  38. to be created for the link layer (code{LL}), the interface queue, the
  39. MAC layer (code{Mac}), and the physical layer (code{Channel}).  Below
  40. is an example of how a new CSMA/CD (Ethernet) LAN is created.
  41. Example:
  42. begin{program}
  43.         $ns make-lan "$n1 $n2" $bw $delay LL Queue/DropTail Mac/Csma/Cd
  44. end{program}
  45. creates a LAN with basic link-layer, drop-tail queue, and CSMA/CD MAC.
  46. section{Components of a LAN}
  47. label{sec:lan_components}
  48. LanLink captures the functionality of the three lowest layers in the
  49. network stack:
  50. begin{enumerate}
  51. item
  52. Link Layer (LL)
  53. item
  54. Medium Access Control (MAC) Layer
  55. item
  56. Physical (PHY) Layer
  57. end{enumerate}
  58. begin{figure}[tb]
  59.   centerline{includegraphics{lan1}}
  60.   caption{Connectivity within a LAN}
  61.   label{fig:lan-connectivity}
  62. end{figure}
  63. Figure~ref{fig:lan-connectivity} illustrates the extended network
  64. stack that makes simulations of local area network possible in ns.  A
  65. packet sent down the stack flows
  66. through the link layer (code{Queue} and code{LL}), the MAC layer
  67. (code{Mac}), and the physical layer (code{Channel} to
  68. code{Classifier/Mac}).  The packet then makes its way up the stack through
  69. the code{Mac}, and the code{LL}.
  70. At the bottom of the stack, the physical layer is composed of two
  71. simulation objects: the code{Channel} and code{Classifier/Mac}.  The
  72. code{Channel} object simulates the shared medium and supports the medium
  73. access mechanisms of the MAC objects on the sending side of the
  74. transmission.  On the receiving side, the code{Classifier/Mac} is
  75. responsible for delivering and optionally replicating packets to the
  76. receiving MAC objects.
  77. Depending on the type of physical layer, the MAC layer must contain a
  78. certain set of functionalities such as: carrier sense, collision
  79. detection, collision avoidance, etc.  Since these functionalities affect
  80. both the sending and receiving sides, they are implemented in a single
  81. code{Mac} object.  For sending, the code{Mac} object must follow a certain
  82. medium access protocol before transmitting the packet on the channel.
  83. For receiving, the MAC layer is responsible for delivering the packet to
  84. the link layer.
  85. Above the MAC layer, the link layer can potentially have many
  86. functionalities such as queuing and link-level retransmission.  The
  87. need of having a wide variety of link-level schemes leads to the
  88. division of functionality into two components: code{Queue} and
  89. code{LL} (link-layer).  The code{Queue} object, simulating the
  90. interface queue, belongs to the same code{Queue} class that is
  91. described in Chapter~ref{chap:qmgmt}.  The code{LL} object implements
  92. a particular data link protocol, such as ARQ.  By combining both the
  93. sending and receiving functionalities into one module, the code{LL}
  94. object can also support other mechanisms such as piggybacking.
  95. section{Channel Class}
  96. label{sec:channel}
  97. The code{Channel} class simulates the actual transmission of the packet
  98. at the physical layer.  The basic code{Channel} implements a shared
  99. medium with support for contention mechanisms.  It allows the MAC to
  100. carry out carrier sense, contention, and collision detection.  If more
  101. than one transmissions overlaps in time, a channel raises the collision
  102. flag.  By checking this flag, the MAC object can implement collision detection
  103. and handling.
  104. Since the transmission time is a function of the number of bits in the
  105. packet and the modulation speed of each individual interface (MAC), the
  106. code{Channel} object only sets its busy signal for the duration
  107. requested by the MAC object.  It also schedules the packets to be
  108. delivered to the destination MAC objects after the transmission time
  109. plus the propagation delay.
  110. subsection{Channel State}
  111. label{sec:channelstate}
  112. The C++ clsref{Channel}{../ns-2/channel.h} includes enough internal
  113. state to schedule packet delivery and detect collisions.  It exports the
  114. following OTcl configuration parameter:
  115. begin{tabularx}{linewidth}{rX}
  116. code{delay_} & propagation delay on the channel \
  117. end{tabularx}
  118. subsection{Example: Channel and classifier of the physical layer}
  119. label{ex:channel}
  120. begin{verbatim}
  121.         set channel_ [new Channel]
  122.         $channel_ set delay_ 4us        # propagation delay
  123.         set mcl_ [new Classifier/Mac]
  124.         $channel_ target $mcl_
  125.         $mcl_ install $mac_DA $recv_iface
  126.                 . . .
  127. end{verbatim}
  128. subsection{Channel Class in C++}
  129. label{sec:channelcplus}
  130. In C++, the class Channel extends the Connector object
  131. with several new methods to
  132. support a variety of MAC protocols.  The class is defined as follow in
  133. nsf{channel.h}:
  134. begin{program}
  135.    class Channel : public Connector {
  136.    public:
  137.         Channel();
  138.         void recv(Packet* p, Handler*);
  139.         virtual int send(Packet* p, double txtime);
  140.         virtual void contention(Packet*, Handler*);
  141.         int hold(double txtime);
  142.         virtual int collision() { return numtx_ > 1; }
  143.         virtual double txstop() { return txstop_; }
  144.                 . . .
  145.    };
  146. end{program}
  147. The important methods of the class code{Channel} are:
  148. begin{itemize}
  149. item  code{txstop()} method returns the time when the channel will become
  150. idle, which can be used by the MAC to implement carrier sense.
  151. item  code{contention()} method allows the MAC to contend for the channel
  152. before sending a packet.  The channel then use this packet to signal the
  153. corresponding code{Mac} object at the end of each contention period.
  154. item  code{collision()} method indicates whether a collision occurs
  155. during the contention period.  When the code{Channel} signal the end of
  156. the contention period, the MAC can use the code{collision()} method to
  157. detect collision.
  158. item  code{send()} method allows the MAC object to transmit a packet on the
  159. channel for a specified duration of time.
  160. item  code{hold()} method allows the MAC object to hold the channel for a
  161. specified duration of time without actually transmitting any packets.
  162. This is useful in simulating the jamming mechanism of some MAC
  163. protocols.
  164. end{itemize}
  165. section{MacClassifier Class}
  166. label{sec:mac_classifier}
  167. The code{MacClassifier} class extends the code{Classifier} class to
  168. implement a simple broadcasting mechanism.  It modifies the
  169. code{recv()} method in the following way: since the replication of a
  170. packet is expensive, normally a unicast packet will be classified by
  171. the MAC destination address code{macDA_} and delivered directly to
  172. the MAC object with such an address.  However, if the destination
  173. object cannot be found or if the MAC destination address is explicitly
  174. set to the broadcast address code{BCAST_ADDR}, the packet will be
  175. replicated and sent to all MACs on the lan excluding the one that is
  176. the source of the packet.  Finally, by setting the bound variable
  177. code{MacClassifier::bcast_} to a non--zero value, will cause
  178. code{MacClassifier} always to replicate packets.
  179. begin{program}
  180.     class MacClassifier : public Classifier {
  181.     public:
  182.         void recv(Packet*, Handler*);
  183.     };
  184.     void MacClassifier::recv(Packet* p, Handler*)
  185.     {
  186.         Mac* mac;
  187.         hdr_mac* mh = hdr_mac::access(p);
  188.         if (bcast_ || mh->macDA() == BCAST_ADDR || (mac = (Mac *)find(p)) == 0) {
  189.                 // Replicate packets to all slots (broadcast)
  190.                 . . .
  191.                 return;
  192.         }
  193.         mac->recv(p);
  194.     }
  195. end{program}
  196. section{MAC Class}
  197. label{sec:mac}
  198. The code{Mac} object simulates the medium access protocols that are
  199. necessary in the shared medium environment such as the wireless and
  200. local area networks.  Since the sending and receiving mechanisms are
  201. tightly coupled in most types of MAC layers,
  202. it is essential for the code{Mac} object to be duplex.
  203. On the sending side, the code{Mac} object is responsible for adding the
  204. MAC header and transmitting the packet onto the channel.  On the
  205. receiving side, the code{Mac} object asynchronously receives packets
  206. from the classifier of the physical layer.  After MAC protocol
  207. processing, it passes the data packet to the link layer.
  208. subsection{Mac State}
  209. label{sec:macstate}
  210. The C++ clsref{Mac}{../ns-2/mac.h} class contains enough internal state
  211. to simulate the particular MAC protocol.  It also exports the following
  212. OTcl configuration parameter:
  213. begin{tabularx}{linewidth}{rX}
  214. code{bandwidth_} & modulation rate of the MAC \
  215. code{hlen_} & additional bytes added to packet for MAC header \
  216. code{label_} & MAC address \
  217. end{tabularx}
  218. subsection{Mac Methods}
  219. label{sec:macmethods}
  220. The clsref{Mac}{../ns-2/mac.cc} class added several Tcl methods for
  221. configuration, in particular, linking with other simulation objects:
  222. begin{tabularx}{linewidth}{rX}
  223. code{channel} & specify the channel for transmission \
  224. code{classifier} & the classifier that deliver packets to receiving MAC \
  225. code{maclist} & a link list of MAC interfaces on the same node \
  226. end{tabularx}
  227. subsection{Mac Class in C++}
  228. label{sec:maccplus}
  229. In C++, the code{Mac} class derives from code{Connector}.  When the
  230. code{recv()} method gets a packet, it identifies the direction of the
  231. packet based on the presence of a callback handler.  If there is a
  232. callback handler, the packet is outgoing, otherwise, it is incoming.
  233. begin{program}
  234.    class Mac : public Connector {
  235.    public:
  236.         Mac();
  237.         virtual void recv(Packet* p, Handler* h);
  238.         virtual void send(Packet* p);
  239.         virtual void resume(Packet* p = 0);
  240.                 . . .
  241.     };
  242. end{program}
  243. When a code{Mac} object receives a packet via its code{recv()} method,
  244. it checks whether the packet is outgoing or incoming.  For an outgoing
  245. packet, it assumes that the link-layer of the sender has obtained the
  246. destination MAC address and filled in the code{macDA_} field of the
  247. MAC header, code{hdr_mac}.  The code{Mac} object fills in the rest of
  248. the MAC header with the source MAC address and the frame type.  It then
  249. passes the packet to its code{send()} method, which carries out the
  250. medium access protocol.  For the basic code{Mac} object, the
  251. code{send} method calls code{txtime()} to compute the transmission
  252. time, then invokes code{Channel::send} to transmit the packet.  
  253. Finally, it 
  254. schedules itself to resume after the transmission time has elapsed.
  255. For an incoming packet, the MAC object does its protocol processing and
  256. passes the packet to the link-layer.
  257. subsection{CSMA-based MAC}
  258. The clsref{CsmaMac}{../ns-2/mac-csma.cc} extends the code{Mac} class
  259. with new methods that implements carrier sense and backoff mechanisms.
  260. The code{CsmaMac::send()} method detects when the channel becomes idle
  261. using code{Channel::txtime()}.  If the channel is busy, the MAC
  262. schedules the next carrier sense at the moment the channel turns idle.
  263. Once the channel is idle, the code{CsmaMac} object initiates the
  264. contention period with code{Channel::contention()}.  At the end of the
  265. contention period, the code{endofContention()} method is invoked.  At
  266. this time, the basic code{CsmaMac} just transmits the packet using
  267. code{Channel::send}.
  268. begin{program}
  269.     class CsmaMac : public Mac {
  270.     public:
  271.         CsmaMac();
  272.         void send(Packet* p);
  273.         void resume(Packet* p = 0);
  274.         virtual void endofContention(Packet* p);
  275.         virtual void backoff(Handler* h, Packet* p, double delay=0);
  276.                 . . .
  277.     };
  278.     class CsmaCdMac : public CsmaMac {
  279.     public:
  280.         CsmaCdMac();
  281.         void endofContention(Packet*);
  282.     };
  283.     class CsmaCaMac : public CsmaMac {
  284.     public:
  285.         CsmaCaMac();
  286.         virtual void send(Packet*);
  287.     };
  288. end{program}
  289. The code{CsmaCdMac} extends code{CsmaMac} to carry out collision
  290. detection procedure of the CSMA/CD (Ethernet) protocol.  When the
  291. channel signals the end of contention period, the code{endofContention}
  292. method checks for collision using the code{Channel::collision()}
  293. method.  If there is a collision, the MAC invokes its code{backoff}
  294. method to schedule the next carrier sense to retransmit the packet.
  295. The code{CsmaCaMac} extends the code{send} method of code{CsmaMac} to
  296. carry out the collision avoidance (CSMA/CA) procedure.  Instead of
  297. transmitting immediately when the channel is idle, the code{CsmaCaMac}
  298. object backs off a random number of slots, then transmits if the channel
  299. remains idle until the end of the backoff period.
  300. section{LL (link-layer) Class}
  301. label{sec:linklayer}
  302. The link-layer object is responsible for simulating the data link
  303. protocols.  Many protocols can be implemented within this layer such
  304. as packet fragmentation and reassembly, and reliable link protocol. 
  305. Another important function of the link layer is setting the MAC
  306. destination address in the MAC header of the packet.  In the current
  307. implementation this task involves two separate issues: finding the
  308. next--hop--node's IP address (routing) and resolving this IP address
  309. into the correct MAC address (ARP).  For simplicity, the default
  310. mapping between MAC and IP addresses is one--to--one, which means that
  311. IP addresses are re--used at the MAC layer.
  312. subsection{LL Class in C++}
  313. label{sec:llcplus}
  314. The C++ class code{LL} derives from the code{LinkDelay} class.  Since
  315. it is a duplex object, it keeps a separate pointer for the send target,
  316. code{sendtarget}, and the receive target, code{recvtarget}.  It also
  317. defines the methods code{recvfrom()} and code{sendto()} to handle the
  318. incoming and outgoing packets respectively.
  319. begin{program}
  320.    class LL : public LinkDelay {
  321.    public:
  322.        LL();
  323.        virtual void recv(Packet* p, Handler* h);
  324.        virtual Packet* sendto(Packet* p, Handler* h = 0);
  325.        virtual Packet* recvfrom(Packet* p);
  326.    
  327.        inline int seqno() { return seqno_; }
  328.        inline int ackno() { return ackno_; }
  329.        inline int macDA() { return macDA_; }
  330.        inline Queue *ifq() { return ifq_; }
  331.        inline NsObject* sendtarget() { return sendtarget_; }
  332.        inline NsObject* recvtarget() { return recvtarget_; }
  333.    
  334.    protected:
  335.        int command(int argc, const char*const* argv);
  336.        void handle(Event* e) { recv((Packet*)e, 0); }
  337.        inline virtual int arp (int ip_addr) { return ip_addr; } 
  338.        int seqno_; // link-layer sequence number
  339.        int ackno_; // ACK received so far
  340.        int macDA_; // destination MAC address
  341.        Queue* ifq_; // interface queue
  342.        NsObject* sendtarget_; // for outgoing packet 
  343.        NsObject* recvtarget_; // for incoming packet
  344.    
  345.        LanRouter* lanrouter_; // for lookups of the next hop
  346.    };
  347. end{program}
  348. subsection{Example: Link Layer configuration}
  349. label{ex:linklayer}
  350. begin{program}
  351.     set ll_  [new LL]
  352.     set ifq_ [new Queue/DropTail]
  353.     $ll_ lanrouter  [new LanRouter $ns $lan] # LanRouter is one object
  354.                                              # per LAN
  355.     $ll_ set delay_ $delay        # link-level overhead
  356.     $ll_ set bandwidth_ $bw       # bandwidth
  357.     $ll_ sendtarget $mac          # interface queue at the sender side
  358.     $ll_ recvtarget $iif          # input interface of the receiver
  359.              . . .
  360. end{program}
  361. section{code{LanRouter} class}
  362. By default, there is just one code{LanRouter} object per LAN, which
  363. is created when a new code{LanNode} is initialized.  For every node
  364. on the LAN, the link layer object (code{LL}) has a pointer to the
  365. code{LanRouter}, so it is able to find the next hop for the packet
  366. that is sent on the LAN:
  367. begin{program}
  368. Packet* LL::sendto(Packet* p, Handler* h)
  369. {        
  370.         int nh = (lanrouter_) ? lanrouter_->next_hop(p) : -1;
  371.         . . .
  372. }
  373. end{program}
  374. code{LanRouter} is able to find the next hop by querying the current
  375. code{RouteLogic}:
  376. begin{program}
  377. int LanRouter::next_hop(Packet *p) {
  378.         int next_hopIP;
  379.         if (enableHrouting_) {
  380.                 routelogic_->lookup_hier(lanaddr_, adst, next_hopIP);
  381.         } else {
  382.                 routelogic_->lookup_flat(lanaddr_, adst, next_hopIP);
  383.         }
  384. end{program}
  385. One limitation of this is that code{RouteLogic} may not be aware of
  386. dynamic changes to the routing.  But it is always possible to derive a
  387. new class from code{LanRouter} so that to re--define its
  388. code{next_hop} method to handle dynamic changes appopriately.
  389. section{Other Components}
  390. label{sec:lan_others}
  391. In addition to the C++ components described above, simulating local area
  392. networks also requires a number of existing components in ns such as
  393. code{Classifier}, code{Queue}, and code{Trace},
  394. code{networkinterface}, etc.  Configuring these
  395. objects requires knowledge of what the user wants to simulate.  The
  396. default configuration is implemented in the two Tcl files mentioned at
  397. the beginning of this chapter.  To obtain more realistic simulations
  398. of wireless networks, one can use the code{ErrorModel} described in
  399. Chapter~ref{chap:error_model}.
  400. section{LANs and ns routing}
  401. label{sec:lan_ns-routing}
  402. When a LAN is created using either code{make-lan} or code{newLan}, a
  403. ``textit{virtual LAN node}'' code{LanNode} is created.
  404. code{LanNode} keeps together all shared objects on the LAN:
  405. code{Channel}, code{Classifier/Mac}, and code{LanRouter}.  Then for
  406. each node on the LAN, a code{LanIface} object is created.
  407. code{LanIface} contains all other objects that are needed on the
  408. per--node basis: a code{Queue}, a link layer (code{LL}),
  409. code{Mac}, etc.  It should be emphasized that code{LanNode} is a
  410. node only for routing algorithms:  code{Node} and code{LanNode} have
  411. very little in common.  One of few things that they share is an
  412. identifier taken from the code{Node} ID--space.  If
  413. textit{hierarchical routing} is used, code{LanNode} textit{has to be
  414. assigned a hierarchical address} just like any other node.  From the
  415. point of view of ns (static) routing, code{LanNode} is just another
  416. node connected to every node on the LAN.
  417. begin{figure}[hbt]
  418. centerline{includegraphics{lan2}}
  419.    caption{Actual LAN configuration (left) and as seen by
  420.    ns routing (right)}
  421.    label{fig:lan-routing1}
  422. end{figure}
  423. Links connecting the code{LanNode} with the nodes on the LAN are also
  424. ``virtual'' (code{Vlink}).  The default routing cost of such a link
  425. is $1/2$, so the cost of traversing two code{Vlink}s
  426. (e.g. textbf{n1 $rightarrow$ LAN $rightarrow$ n2}) is counted as just one
  427. hop.  
  428. Most important method of code{Vlink} is the one that gives the head
  429. of the link:
  430. begin{program}
  431. Vlink instproc head {} {
  432.     $self instvar lan_ dst_ src_
  433.     if {$src_ == [$lan_ set id_]} {
  434.         # if this is a link FROM the lan vnode, 
  435.         # it doesn't matter what we return, because
  436.         # it's only used by $lan add-route (empty)
  437.         return ""
  438.     } else {
  439.         # if this is a link TO the lan vnode, 
  440.         # return the entry to the lanIface object
  441.         set src_lif [$lan_ set lanIface_($src_)]
  442.         return [$src_lif entry]
  443.     }
  444. }
  445. end{program}
  446. This method is used by static (default) routing to install correct
  447. routes at a  node (see code{Simulator} methods \ code{compute-flat-routes} and
  448. code{compute-hier-routes} in code{tcl/lib/ns-route.tcl}, as well
  449. as code{Node} methods code{add-route} and code{add-hroute} in
  450. code{tcl/lib/ns-node.tcl}).  
  451. From the code fragment above it can be seen that it returns LAN
  452. interface of the node as a head of the link to be installed in the
  453. appropriate classifier. 
  454. Thus, code{Vlink} textit{does not impose any delay on the packet}
  455. and serves the only purpose to install LAN interfaces instead of
  456. normal links at nodes' classifiers.  
  457. Note, that this design allows to have nodes connected by parallel
  458. LANs, while in the current implementation it is impossible to have
  459. nodes connected by parallel simple links and use them both (the array
  460. code{Simulator instvar link_} holds the link object for each
  461. connected pair of source and destination, and it can be only one
  462. object per source/destination pair).
  463. section{Commands at a glance}
  464. label{sec:lancommand}
  465. The following is a list of lan related commands commonly used in
  466. simulation scripts:
  467. begin{flushleft}
  468. code{$ns_ make-lan  <nodelist> <bw> <delay> <LL> <ifq> <MAC> <channel> <phy>}\
  469. Creates a lan from a set of nodes given by <nodelist>. Bandwidth, delay characteristics
  470. along with the link-layer, Interface queue, Mac layer and channel type for the
  471. lan also needs to be defined. Default values used are as follows:\
  472. <LL> .. LL\
  473. <ifq>.. Queue/DropTail\
  474. <MAC>.. Mac\
  475. <channel>.. Channel and \
  476. <phy>.. Phy/WiredPhy
  477. code{$ns_ newLan <nodelist> <BW> <delay> <args>}\
  478. This command creates a lan similar to make-lan described above. But this
  479. command can be used for finer control whereas make-lan is a more convinient and
  480. easier command. For example newLan maybe used to create a lan with hierarchical
  481. addresses. See ns/tcl/ex/{vlantest-hier.tcl, vlantest-mcst.tcl, lantest.tcl,
  482. mac-test.tcl} for usage of newLan. The possible argument types that can be
  483. passed are LL, ifq, MAC, channel, phy and address.
  484. code{$lannode cost <c>}\
  485. This assigns a cost of c/2 to each of the (uni-directional) links in the lan.
  486. code{$lannode cost?}\
  487. Returns the cost of (bi-directional) links in the lan, i.e c.
  488. Internal procedures :
  489. code{$lannode addNode <nodes> <bw> <delay> <LL> <ifq> <MAC> <phy>}\
  490. Lan is implemented as a virtual node. The LanNode mimics a real node and uses
  491. an address (id) from node's address space.
  492. This command adds a list of <nodes> to the lan represented by lannode.
  493. The bandwidth, delay and network characteristics of nodes are given by
  494. the above arguments. This is an internal command used by make-lan and newLan.
  495. code{$lannode id}\
  496. Returns the virtual node's id.
  497. code{$lannode node-addr}\
  498. Returns virtual nodes's address.
  499. code{$lannode dump-namconfig}\
  500. This command creates a given lan layout in nam. This function may be changed
  501. to redefine the lan layout in a different way.
  502. code{$lannode is-lan?}\
  503. This command always returns 1, since the node here is a virtual node
  504. representing a lan. The corresponding command for base class Node 
  505. code{$node is-lan?} always returns a 0.
  506. end{flushleft}
  507. %end{document}
  508. endinput