📄 ospf_sim.tcl
字号:
################################################################ Add a group member to a particular network segment###############################################################proc membership {prefix group} { global networks global network_att if {[lsearch $networks $prefix] != -1} { lappend network_att($prefix,groups) $group put_message "membership $prefix $group" }}################################################################ Limit the number of p-p adjacencies from this router to# any of its neighbors###############################################################proc PPAdjLimit {rtr_id nadj} { global router_att set router_att($rtr_id,PPAdjLimit) $nadj}################################################################ Set *all* simulated routers to randomly refresh.# By default, this function is disabled.###############################################################proc random_refresh {} { global random_refresh_flag set random_refresh_flag 1}################################################################ Send entire configuration to a# given router (i.e., simulated ospfd).###############################################################proc sendcfg {rtr_id} { global router_att area_att ifc_att vlink_att global aggr_att route_att host_att nbr_att node_att global networks network_att random_refresh_flag sendgen $rtr_id $router_att($rtr_id,host) $router_att($rtr_id,mospf) \ $router_att($rtr_id,PPAdjLimit) $random_refresh_flag foreach a $router_att($rtr_id,areas) { sendarea $rtr_id $a $area_att($a,stub) $area_att($a,default_cost) \ $area_att($a,import) } foreach i $node_att($rtr_id,interfaces) { sendifc $rtr_id $ifc_att($i,port) $ifc_att($i,type) \ $ifc_att($i,area) $ifc_att($i,addr) $ifc_att($i,cost) \ $i $ifc_att($i,prefix) $ifc_att($i,demand) \ $ifc_att($i,enabled) $ifc_att($i,passive) $ifc_att($i,ospf) \ $ifc_att($i,drpri) set prefix $ifc_att($i,prefix) if {[lsearch $networks $prefix] != -1} { foreach group $network_att($prefix,groups) { sendgrp $rtr_id $group $ifc_att($i,port) } } } foreach vl $router_att($rtr_id,vlinks) { sendvl $rtr_id $vlink_att($vl,area) $vlink_att($vl,endpt) } foreach nbr $router_att($rtr_id,nbrs) { sendnbr $rtr_id $nbr_att($nbr,addr) $nbr_att($nbr,drpri) } foreach aggr $router_att($rtr_id,aggrs) { sendagg $rtr_id $aggr_att($aggr,area) $aggr_att($aggr,prefix) \ $aggr_att($aggr,noadv) } foreach host $router_att($rtr_id,hosts) { sendhost $rtr_id $host_att($host,prefix) $host_att($host,area) } foreach r $router_att($rtr_id,extrts) { sendextrt $rtr_id $route_att($r,prefix) $route_att($r,nh) \ $route_att($r,etype) $route_att($r,cost) $route_att($r,noadv) }}################################################################ TCL code for the OSPF simulator###############################################################global {node_binding}global {ifc_binding}################################################################ Draw a new OSPF router# id is the OSPF Router ID# label is how it will be named on the map# x and y will be its coordinates, in pixels###############################################################proc draw_router {id} { global node_att node_binding # draw router set x $node_att($id,x) set y $node_att($id,y) set label $id set new [.map create rectangle [expr $x-25] [expr $y-32] \ [expr $x+25] [expr $y+32] -fill red \ -tags [list node rtr $id rtrbox$id]] set node_binding($new) $id set new [.map create line [expr $x-25] [expr $y+26] [expr $x+25] \ [expr $y+26] -tags [list node rtr $id]] set node_binding($new) $id set new [.map create line [expr $x-25] [expr $y+20] [expr $x+25] \ [expr $y+20] -tags [list node rtr $id]] set node_binding($new) $id set new [.map create line [expr $x-25] [expr $y+14] [expr $x+25] \ [expr $y+14] -tags [list node rtr $id]] set node_binding($new) $id set new [.map create line [expr $x-25] [expr $y+8] [expr $x+25] \ [expr $y+8] -tags [list node rtr $id]] set node_binding($new) $id set new [.map create rectangle [expr $x+8] [expr $y-27] [expr $x+20] \ [expr $y-15] -fill black -tags [list node rtr $id]] set node_binding($new) $id set new [.map create text [expr $x] [expr $y-8] -text $label \ -anchor center -tags [list node rtr $id]] set node_binding($new) $id}################################################################ Draw a new network# cidr is its cidr address (e.g., 10/8)# x and y will be its coordinates, in pixels###############################################################proc draw_network {cidr} { global node_att node_binding set x $node_att($cidr,x) set y $node_att($cidr,y) set new [.map create oval [expr $x-35] [expr $y-15] \ [expr $x+35] [expr $y+15] -fill white \ -tags [list node net $cidr]] set node_binding($new) $cidr set new [.map create text $x $y -text $cidr -anchor center \ -tags [list node net $cidr]] set node_binding($new) $cidr}################################################################ Draw an interface between a router and a network# index is the index into the ifc_att array# id is the router's OSPF router ID# cidr is the network's CIDR address###############################################################proc draw_interface {index id cidr} { global node_att ifc_att global ifc_binding set new [.map create line $node_att($id,x) $node_att($id,y) \ $node_att($cidr,x) $node_att($cidr,y) \ -tags [list ifc]] .map lower $new set ifc_att($index,end1) $id set ifc_att($index,end2) $cidr set ifc_att($index,mapid) $new set ifc_binding($new) $index}################################################################ Draw a pplink# interfaces at either end occupy separate# entries in ifc_att###############################################################proc draw_pplink {index1 id1 index2 id2} { global node_att ifc_att global ifc_binding set new [.map create line $node_att($id1,x) $node_att($id1,y) \ $node_att($id2,x) $node_att($id2,y) \ -tags [list ifc]] .map lower $new set ifc_att($index1,end1) $id1 set ifc_att($index1,end2) $id2 set ifc_att($index1,mapid) $new set ifc_att($index2,end1) $id2 set ifc_att($index2,end2) $id1 set ifc_att($index2,mapid) $new set ifc_binding($new) $index1}################################################################ Move a router or network on the map# called internally due to mouse manipulations on the map# Moves all interfaces attached to the object as well###############################################################proc move_node {id xincr yincr} { global node_att ifc_att .map move $id $xincr $yincr set node_att($id,x) [expr $node_att($id,x)+$xincr] set node_att($id,y) [expr $node_att($id,y)+$yincr] foreach ifc $node_att($id,interfaces) { redraw_interface $ifc }}################################################################ Redraw an interface, probably because one# of its endpoints has moved.###############################################################proc redraw_interface {index} { global ifc_att node_att set mapid $ifc_att($index,mapid) set id1 $ifc_att($index,end1) set id2 $ifc_att($index,end2) if {$ifc_att($index,enabled) == 1} { set color "black" } else { set color "red" } .map coords $mapid $node_att($id1,x) $node_att($id1,y) \ $node_att($id2,x) $node_att($id2,y) .map itemconfigure $mapid -fill $color}################################################################ put_message string# Place a particular message at the bottom of the window###############################################################proc put_message {m} { .trailer.message configure -text $m}################################################################ Show simulated time# Must be changed if TICKS_PER_SECOND is changed in sim.h###############################################################proc show_time {ticks} { global sec tenths set sec [expr $ticks/20] set tenths [expr ($ticks%20)/2] .trailer.time configure -text "Time $sec.$tenths"}################################################################ Select a router using the mouse,# and then execute the specified command###############################################################proc SelectRouter {cmd} { global selectrouter_cmd put_message "Double left click on router" set selectrouter_cmd $cmd .map bind rtr <Double-Button-1> { global node_binding global selectrouter_cmd set curNode [.map find withtag current] put_message "" $selectrouter_cmd $node_binding($curNode) .map bind rtr <Double-Button-1> {} }}################################################################ Add a router, from the graphical interface# Multi-step process:# AddRouter - finds place on map# add_router_menu - inputs parameters (like Router ID)# add_router_complete - finishes up###############################################################proc AddRouter {} { put_message "left click on router's position" bind .map <Button-1> {add_router_menu %x %y}}proc add_router_menu {x y} { global add_router_x add_router_y add_router_id add_router_mospf bind .map <Button-1> {} put_message "" set add_router_x [.map canvasx $x] set add_router_y [.map canvasy $y] set w .addrouter toplevel $w wm title $w "Add Router" frame $w.f0 frame $w.f2 pack $w.f2 -side bottom -fill x pack $w.f0 -fill x label $w.f0.id -text "Router ID : " pack $w.f0.id -side left entry $w.f0.id_e -width 20 -textvariable add_router_id pack $w.f0.id_e -side right checkbutton $w.mospf -text "mospf" -variable add_router_mospf pack $w.mospf -side top button $w.f2.ok -text "OK" -command [list add_router_complete $w] button $w.f2.quit -text "Quit" -command [list destroy $w] pack $w.f2.quit $w.f2.ok -side left -expand 1}proc add_router_complete {w} { global add_router_x add_router_y add_router_id add_router_mospf destroy $w put_message "router $add_router_id $add_router_x $add_router_y $add_router_mospf" router $add_router_id $add_router_x $add_router_y $add_router_mospf}################################################################ Add a network, from the graphical interface# Like adding a router, a multi-step process:# AddNetwork - finds place on map# add_network_menu - inputs parameters (like Router ID)# add_network_complete - finishes up###############################################################proc AddNetwork {} { put_message "left click on network's position" bind .map <Button-1> {add_network_menu %x %y}}proc add_network_menu {x y} { global add_network_x add_network_y add_network_prefix global add_network_type add_network_area bind .map <Button-1> {} put_message "" set add_network_x [.map canvasx $x] set add_network_y [.map canvasy $y] set w .addnetwork toplevel $w wm title $w "Add Network" frame $w.f0 frame $w.fl frame $w.fr frame $w.f2 frame $w.f3 pack $w.f3 -side bottom -fill x pack $w.f0 -fill x pack $w.f2 -fill x pack $w.fl $w.fr -side left -expand yes label $w.f0.id -text "Network Prefix : " pack $w.f0.id -side left entry $w.f0.id_e -width 20 -textvariable add_network_prefix pack $w.f0.id_e -side right label $w.f2.id -text "Area ID : " pack $w.f2.id -side left entry $w.f2.id_e -width 20 -textvariable add_network_area pack $w.f2.id_e -side right label $w.fl.type -text "Network type :" pack $w.fl.type -side left radiobutton $w.fr.broadcast -text "broadcast" -variable add_network_type -value 0 radiobutton $w.fr.nbma -text "nbma" -variable add_network_type -value 1 radiobutton $w.fr.ptmp -text "Point-to-MultiPoint" -variable add_network_type -value 2 pack $w.fr.broadcast $w.fr.nbma $w.fr.ptmp -side top -anchor w button $w.f3.ok -text "OK" -command [list add_network_complete $w] button $w.f3.quit -text "Quit" -command [list destroy $w] pack $w.f3.quit $w.f3.ok -side left -expand 1}proc add_network_complete {w} { global add_network_x add_network_y add_network_prefix global add_network_type add_network_area destroy $w if {$add_network_type == 0} { put_message "broadcast $add_network_prefix $add_network_x $add_network_y 0" broadcast $add_network_prefix $add_network_area $add_network_x $add_network_y 0 } if {$add_network_type == 1} { put_message "nbma $add_network_prefix $add_network_x $add_network_y 0" nbma $add_network_prefix $add_network_area $add_network_x $add_network_y 0 } if {$add_network_type == 2} { put_message "ptmp $add_network_prefix $add_network_x $add_network_y 0" ptmp $add_network_prefix $add_network_area $add_network_x $add_network_y 0 }}################################################################ Add a network interface# Point-to-point links and virtual links handled elsewhere# Takes place in the following steps# AddInterface - clicks on router# add_interface_menu - inputs parameters (address, cost)# add_interface_complete - finishes up###############################################################proc add_interface_menu {rtr} { global add_interface_router add_interface_addr global add_interface_cost global add_interface_passive add_interface_ospf set add_interface_router $rtr set w .addinterface toplevel $w wm title $w "Add Interface" label $w.hdr -wraplength 2i -justify left -text "You are adding an interface on router $add_interface_router." pack $w.hdr -side top frame $w.f0 frame $w.f1 frame $w.fb
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -