📄 ns-node.tcl
字号:
## Copyright (c) 1996-1998 Regents of the University of California.# All rights reserved.# # Redistribution and use in source and binary forms, with or without# modification, are permitted provided that the following conditions# are met:# 1. Redistributions of source code must retain the above copyright# notice, this list of conditions and the following disclaimer.# 2. Redistributions in binary form must reproduce the above copyright# notice, this list of conditions and the following disclaimer in the# documentation and/or other materials provided with the distribution.# 3. All advertising materials mentioning features or use of this software# must display the following acknowledgement:# This product includes software developed by the MASH Research# Group at the University of California Berkeley.# 4. Neither the name of the University nor of the Research Group may be# used to endorse or promote products derived from this software without# specific prior written permission.# # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF# SUCH DAMAGE.## @(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/tcl/lib/ns-node.tcl,v 1.71 2000/07/22 23:52:34 xuanc Exp $## for MobileIP# Class Classifier/Port/MIP -superclass Classifier/Port Classifier/Port/Reserve instproc init args { eval $self next $self reserve-port 2}#Class NodeNode set nn_ 0Node proc getid {} { set id [Node set nn_] Node set nn_ [expr $id + 1] return $id}Node instproc init args { eval $self next $args $self instvar np_ id_ agents_ dmux_ neighbor_ rtsize_ address_ $self instvar nodetype_ $self instvar multiPath_ set nodetype_ [[Simulator instance] get-nodetype] set neighbor_ "" set agents_ "" set dmux_ "" set np_ 0 set id_ [Node getid] set rtsize_ 0# set address_ $args $self set-node-address$nodetype_ $args $self mk-default-classifier$nodetype_# $self mk-default-classifier $self cmd addr $address_; # new by tomh set multiPath_ [$class set multiPath_]}Node instproc set-node-address { args } {}Node instproc set-node-addressMIPBS { args } {}Node instproc set-node-addressMIPMH { args } {}Node instproc set-node-addressMobile { args } { $self instvar nifs_ arptable_ $self instvar netif_ mac_ ifq_ ll_ $self instvar X_ Y_ Z_ set X_ 0.0 set Y_ 0.0 set Z_ 0.0 set arptable_ "" ;# no ARP table yet set nifs_ 0 ;# number of network interfaces}Node instproc set-node-addressHier {args} { $self instvar address_ set address_ $args}Node instproc set-node-addressBase {args} {}Node instproc mk-default-classifierMIPMH {} { $self mk-default-classifierBase}Node instproc mk-default-classifierMIPBS {} { $self mk-default-classifierBase}Node instproc mk-default-classifierBase {} { $self mk-default-classifierHier}Node instproc mk-default-classifierHier {} { $self instvar np_ id_ classifiers_ agents_ dmux_ neighbor_ address_ # puts "id=$id_" set levels [AddrParams set hlevel_] for {set n 1} {$n <= $levels} {incr n} { set classifiers_($n) [new Classifier/Addr] $classifiers_($n) set mask_ [AddrParams set NodeMask_($n)] $classifiers_($n) set shift_ [AddrParams set NodeShift_($n)] }}# mobileNodeNode instproc mk-default-classifierMobile {} { $self mk-default-classifier}## splitting up address str: used by other non-hier classesNode instproc split-addrstr addrstr { set L [split $addrstr .] return $L}Node instproc mk-default-classifier {} { $self instvar address_ classifier_ id_ set classifier_ [new Classifier/Hash/Dest 32] # set up classifer as a router (default value 8 bit of addr and 8 bit port) $classifier_ set mask_ [AddrParams set NodeMask_(1)] $classifier_ set shift_ [AddrParams set NodeShift_(1)] if ![info exists address_] { set address_ $id_ }}Node instproc enable-mcast sim { $self instvar classifier_ multiclassifier_ ns_ switch_ mcastproto_ $self set ns_ $sim $self set switch_ [new Classifier/Addr] # # set up switch to route unicast packet to slot 0 and # multicast packets to slot 1 # [$self set switch_] set mask_ [AddrParams set McastMask_] [$self set switch_] set shift_ [AddrParams set McastShift_] # # create a classifier for multicast routing # $self set multiclassifier_ [new Classifier/Multicast/Replicator] [$self set multiclassifier_] set node_ $self $self set mrtObject_ [new mrtObject $self] $switch_ install 0 $classifier_ $switch_ install 1 $multiclassifier_ }Node instproc add-neighbor p { $self instvar neighbor_ lappend neighbor_ $p}## increase the routing table size counter - keeps track of rtg table # size for each node#Node instproc incr-rtgtable-size {} { $self instvar rtsize_ set rtsize_ [expr $rtsize_ + 1]}Node instproc entry {} { #set nodetype [[Simulator instance] get-nodetype] $self instvar nodetype_ return [$self entry-New$nodetype_]}Node instproc entry-NewMIPBS {} { return [$self entry-NewBase]}Node instproc entry-NewMIPMH {} { return [$self entry-NewBase]}Node instproc entry-NewBase {} { $self instvar ns_ if ![info exist ns_] { set ns_ [Simulator instance] } if [$ns_ multicast?] { $self instvar switch_ return $switch_ } $self instvar classifiers_ return $classifiers_(1)}Node instproc entry-New {} { if [info exists router_supp_] { return $router_supp_ } if ![info exist ns_] { set ns_ [Simulator instance] } if [$ns_ multicast?] { $self instvar switch_ return $switch_ } $self instvar classifier_ return $classifier_}Node instproc entry-NewMobile {} { return [$self entry-New]}Node instproc add-route { dst target } { $self instvar classifier_ $classifier_ install $dst $target $self incr-rtgtable-size}Node instproc get-nam-traceall {args} { $self instvar namtraceFile_ set file [lindex $args 0] set namtraceFile_ $file}Node instproc id {} { $self instvar id_ return $id_}Node instproc node-addr {} { $self instvar address_ return $address_}Node instproc alloc-port { nullagent } { $self instvar dmux_ np_ set p [$dmux_ alloc-port $nullagent] if { $np_ < $p } { set np_ $p } if {$np_ > [$dmux_ set mask_] && [$dmux_ set mask_] > 0 } { puts stderr "No of ports($np_) attached to $self node is greater than allowed" } return $p}## Attach an agent to a node. Pick a port and# bind the agent to the port number.#Node instproc attach { agent { port "" } } { $self instvar agents_ address_ dmux_ classifier_ $self instvar classifiers_ # # assign port number (i.e., this agent receives # traffic addressed to this host and port) # lappend agents_ $agent # # Check if number of agents exceeds length of port-address-field size # set mask [AddrParams set ALL_BITS_SET] set shift 0 # The following code is no longer needed. It is unlikely that # a node holds billions of agents# if {[expr [llength $agents_] - 1] > $mask} {# error "\# of agents attached to node $self exceeds port-field length of $mask bits\n"# } # # Attach agents to this node (i.e., the classifier inside). # We call the entry method on ourself to find the front door # (e.g., for multicast the first object is not the unicast # classifier) # Also, stash the node in the agent and set the # local addr of this agent. # $agent set node_ $self if [Simulator set EnableHierRt_] { $agent set agent_addr_ [AddrParams set-hieraddr $address_] } else { $agent set agent_addr_ [expr ($address_ & \ [AddrParams set NodeMask_(1)]) \ << [AddrParams set NodeShift_(1) ]] } # # If a port demuxer doesn't exist, create it. # if { $dmux_ == "" } { set dmux_ [new Classifier/Port] $dmux_ set mask_ $mask $dmux_ set shift_ $shift # # point the node's routing entry to itself # at the port demuxer (if there is one) # if {[Simulator set EnableHierRt_]} { $self add-hroute $address_ $dmux_ } else { $self add-route $address_ $dmux_ } } if {$port == ""} { set ns_ [Simulator instance] $ns_ instvar nullAgent_ set port [$self alloc-port $nullAgent_] } $agent set agent_port_ $port $self add-target $agent $port}## add target to agent and add entry for port-id in port-dmux#Node instproc add-target {agent port} { #set nodetype [[Simulator instance] get-nodetype] $self instvar nodetype_ $self add-target-New$nodetype_ $agent $port} Node instproc add-target-New {agent port} { $self instvar dmux_ # # Send Target # $agent target [$self entry] # # Recv Target # $dmux_ install $port $agent} Node instproc add-target-NewBase {agent port} { $self add-target-NewMobile $agent $port}Node instproc add-target-NewHier {agent port} { $self add-target-New $agent $port}## Detach an agent from a node.#Node instproc detach { agent nullagent } { $self instvar agents_ dmux_ # # remove agent from list # set k [lsearch -exact $agents_ $agent] if { $k >= 0 } { set agents_ [lreplace $agents_ $k $k] } # # sanity -- clear out any potential linkage # $agent set node_ "" $agent set agent_addr_ 0 $agent target $nullagent set port [$agent set agent_port_] #Install nullagent to sink transit packets # $dmux_ clear $port $dmux_ install $port $nullagent}Node instproc agent port { $self instvar agents_ foreach a $agents_ { if { [$a set agent_port_] == $port } { return $a } } return ""}## reset all agents attached to this node#Node instproc reset {} { #set nodetype [[Simulator instance] get-nodetype] $self instvar nodetype_ $self do-reset$nodetype_ # $self instvar agents_# foreach a $agents_ {# $a reset# }}Node instproc do-reset { } { $self instvar agents_ foreach a $agents_ { $a reset }}Node instproc do-resetMobile {} { $self instvar arptable_ nifs_ $self instvar netif_ mac_ ifq_ ll_ $self instvar imep_ for {set i 0} {$i < $nifs_} {incr i} { $netif_($i) reset $mac_($i) reset $ll_($i) reset $ifq_($i) reset if { [info exists opt(imep)] && $opt(imep) == "ON" } { $imep_($i) reset } } if { $arptable_ != "" } { $arptable_ reset }}Node instproc do-resetBase {} { $self do-resetMobile}Node instproc do-resetHier {} { $self do-reset}## Some helpers#Node instproc neighbors {} { $self instvar neighbor_ return [lsort $neighbor_]}## Helpers for interface stuff#Node instproc attachInterfaces ifs { $self instvar ifaces_ set ifaces_ $ifs foreach ifc $ifaces_ { $ifc setNode $self }}Node instproc addInterface { iface } { $self instvar ifaces_ lappend ifaces_ $iface# $iface setNode $self }Node instproc createInterface { num } { $self instvar ifaces_ set newInterface [new NetInterface] if { $num < 0 } { return 0 } $newInterface set-label $num return 1}Node instproc getInterfaces {} { $self instvar ifaces_ return $ifaces_}Node instproc getNode {} { return $self}## helpers for PIM stuff#Node instproc get-vif {} { $self instvar vif_ if [info exists vif_] { return $vif_ } set vif_ [new NetInterface] $self addInterface $vif_ return $vif_}# List of corresponding peer TCP hosts from this node, used in IntTcpNode instproc addCorresHost {addr cw mtu maxcw wndopt } { $self instvar chaddrs_ if { ![info exists chaddrs_($addr)] } { set chost [new Agent/Chost $addr $cw $mtu $maxcw $wndopt] set chaddrs_($addr) $chost } return $chaddrs_($addr)}Node instproc createTcpSession {dst} { $self instvar tcpSession_ if { ![info exists tcpSession_($dst)] } { set tcpsession [new Agent/TCP/Session] $self attach $tcpsession $tcpsession set dst_ $dst set tcpSession_($dst) $tcpsession } return $tcpSession_($dst)}Node instproc getTcpSession {dst} { $self instvar tcpSession_ if { [info exists tcpSession_($dst)] } { return $tcpSession_($dst) } else { puts "In getTcpSession(): no session exists for destination [$dst set addr_]" return "" }}Node instproc existsTcpSession {dst} { $self instvar tcpSession_ if { [info exists tcpSession_($dst)] } { return 1 } else { return 0 }}## Node support for detailed dynamic routing#Node instproc init-routing rtObject { $self instvar multiPath_ routes_ rtObject_ set multiPath_ [$class set multiPath_] set nn [$class set nn_] for {set i 0} {$i < $nn} {incr i} { set routes_($i) 0 } if ![info exists rtObject_] { $self set rtObject_ $rtObject } $self set rtObject_}Node instproc rtObject? {} { $self instvar rtObject_ if ![info exists rtObject_] { return "" } else { return $rtObject_ }}## Node support for equal cost multi path routing#Node instproc add-routes {id ifs} { $self instvar classifier_ multiPath_ routes_ mpathClsfr_ if !$multiPath_ { if {[llength $ifs] > 1} { warn "$class::$proc cannot install multiple routes" set ifs [lindex $ifs 0] } $self add-route $id [$ifs head] set routes_($id) 1 return } if {$routes_($id) <= 0 && [llength $ifs] == 1 && \ ![info exists mpathClsfr_($id)]} { $self add-route $id [$ifs head] set routes_($id) 1 } else { if ![info exists mpathClsfr_($id)] { # 1. get new MultiPathClassifier, # 2. migrate existing routes to that mclassifier # 3. install the mclassifier in the node classifier_ # set mpathClsfr_($id) [new Classifier/MultiPath] if {$routes_($id) > 0} { assert {$routes_($id) == 1} $mpathClsfr_($id) installNext [$classifier_ in-slot? $id] } $classifier_ install $id $mpathClsfr_($id) } foreach L $ifs { $mpathClsfr_($id) installNext [$L head] incr routes_($id) } }}Node instproc delete-routes {id ifs nullagent} { $self instvar mpathClsfr_ routes_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -