1147 lines
32 KiB
Tcl
1147 lines
32 KiB
Tcl
#
|
|
# Copyright 2005-2008 University of Zagreb, Croatia.
|
|
#
|
|
# 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.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR 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.
|
|
#
|
|
# This work was supported in part by the Croatian Ministry of Science
|
|
# and Technology through the research contract #IP-2003-143.
|
|
#
|
|
|
|
#****h* imunes/cfgparse.tcl
|
|
# NAME
|
|
# cfgparse.tcl -- file used for parsing the configuration
|
|
# FUNCTION
|
|
# This module is used for parsing the configuration, i.e. reading the
|
|
# configuration from a file or a string and writing the configuration
|
|
# to a file or a string. This module also contains a function for returning
|
|
# a new ID for nodes, links and canvases.
|
|
#****
|
|
|
|
#****f* nodecfg.tcl/dumpputs
|
|
# NAME
|
|
# dumpputs -- puts a string to a file or a string configuration
|
|
# SYNOPSIS
|
|
# dumpputs $method $destination $string
|
|
# FUNCTION
|
|
# Puts a sting to the file or appends the string configuration (used for
|
|
# undo functions), the choice depends on the value of method parameter.
|
|
# INPUTS
|
|
# * method -- method used. Possiable values are file (if saving the string
|
|
# to the file) and string (if appending the string configuration)
|
|
# * dest -- destination used. File_id for files, and string name for string
|
|
# configuration
|
|
# * string -- the string that is inserted to a file or appended to the string
|
|
# configuartion
|
|
#****
|
|
|
|
proc dumpputs {method dest string} {
|
|
switch -exact -- $method {
|
|
file {
|
|
puts $dest $string
|
|
}
|
|
string {
|
|
global $dest
|
|
append $dest "$string
|
|
"
|
|
}
|
|
}
|
|
}
|
|
|
|
#****f* nodecfg.tcl/dumpCfg
|
|
# NAME
|
|
# dumpCfg -- puts the current configuraton to a file or a string
|
|
# SYNOPSIS
|
|
# dumpCfg $method $destination
|
|
# FUNCTION
|
|
# Writes the working (current) configuration to a file or a string.
|
|
# INPUTS
|
|
# * method -- used method. Possiable values are file (saving current congif
|
|
# to the file) and string (saving current config in a string)
|
|
# * dest -- destination used. File_id for files, and string name for string
|
|
# configurations
|
|
#****
|
|
|
|
proc dumpCfg {method dest} {
|
|
global node_list plot_list link_list canvas_list annotation_list
|
|
|
|
global g_comments
|
|
if { [info exists g_comments] && $g_comments != "" } {
|
|
dumpputs $method $dest "comments \{"
|
|
foreach line [split $g_comments "\n"] { dumpputs $method $dest "$line" }
|
|
dumpputs $method $dest "\}"
|
|
dumpputs $method $dest ""
|
|
}
|
|
|
|
foreach node $node_list {
|
|
global $node
|
|
upvar 0 $node lnode
|
|
dumpputs $method $dest "node $node \{"
|
|
foreach element $lnode {
|
|
if { "[lindex $element 0]" == "network-config" } {
|
|
dumpputs $method $dest " network-config \{"
|
|
foreach line [lindex $element 1] {
|
|
dumpputs $method $dest " $line"
|
|
}
|
|
dumpputs $method $dest " \}"
|
|
} elseif { "[lindex $element 0]" == "custom-config" } {
|
|
dumpputs $method $dest " custom-config \{"
|
|
foreach line [lindex $element 1] {
|
|
if { $line != {} } {
|
|
if { [catch {set str [lindex $line 0]} err] } {
|
|
puts "error loading config: $err"
|
|
puts "problem section: [lindex $element 0]"
|
|
puts "problem line: $line"
|
|
set str ""
|
|
}
|
|
if { $str == "config" } {
|
|
dumpputs $method $dest " config \{"
|
|
foreach element [lindex $line 1] {
|
|
dumpputs $method $dest " $element"
|
|
}
|
|
dumpputs $method $dest " \}"
|
|
} else {
|
|
dumpputs $method $dest " $line"
|
|
}
|
|
}
|
|
}
|
|
dumpputs $method $dest " \}"
|
|
} elseif { "[lindex $element 0]" == "ipsec-config" } {
|
|
dumpputs $method $dest " ipsec-config \{"
|
|
foreach line [lindex $element 1] {
|
|
if { $line != {} } {
|
|
dumpputs $method $dest " $line"
|
|
}
|
|
}
|
|
dumpputs $method $dest " \}"
|
|
} elseif { "[lindex $element 0]" == "custom-pre-config-commands" } {
|
|
#Boeing custom pre config commands
|
|
dumpputs $method $dest " custom-pre-config-commands \{"
|
|
foreach line [lindex $element 1] {
|
|
dumpputs $method $dest " $line"
|
|
}
|
|
dumpputs $method $dest " \}"
|
|
} elseif { "[lindex $element 0]" == "custom-post-config-commands" } {
|
|
#Boeing custom post config commands
|
|
dumpputs $method $dest " custom-post-config-commands \{"
|
|
foreach line [lindex $element 1] {
|
|
dumpputs $method $dest " $line"
|
|
}
|
|
dumpputs $method $dest " \}"
|
|
} elseif { "[lindex $element 0]" == "ine-config" } {
|
|
# Boeing: INE config support
|
|
dumpputs $method $dest " ine-config \{"
|
|
foreach line [lindex $element 1] {
|
|
dumpputs $method $dest " $line"
|
|
}
|
|
dumpputs $method $dest " \}"
|
|
# end Boeing
|
|
} else {
|
|
dumpputs $method $dest " $element"
|
|
}
|
|
}
|
|
dumpputs $method $dest "\}"
|
|
dumpputs $method $dest ""
|
|
}
|
|
|
|
foreach obj "link annotation canvas plot" {
|
|
upvar 0 ${obj}_list obj_list
|
|
foreach elem $obj_list {
|
|
global $elem
|
|
upvar 0 $elem lelem
|
|
dumpputs $method $dest "$obj $elem \{"
|
|
foreach element $lelem {
|
|
dumpputs $method $dest " $element"
|
|
}
|
|
dumpputs $method $dest "\}"
|
|
dumpputs $method $dest ""
|
|
}
|
|
}
|
|
|
|
global g_traffic_flows
|
|
if { [info exists g_traffic_flows] && [llength $g_traffic_flows] > 0 } {
|
|
dumpputs $method $dest "traffic \{"
|
|
foreach flow $g_traffic_flows {
|
|
dumpputs $method $dest " $flow"
|
|
}
|
|
dumpputs $method $dest "\}"
|
|
dumpputs $method $dest ""
|
|
}
|
|
|
|
global g_hook_scripts
|
|
if { [info exists g_hook_scripts] && [llength $g_hook_scripts] > 0 } {
|
|
foreach hook $g_hook_scripts {
|
|
set name [lindex $hook 0]
|
|
set state [lindex $hook 1]
|
|
set script [lindex $hook 2]
|
|
dumpputs $method $dest "hook $state:$name \{"
|
|
# remove the final newline here because dumpputs adds a
|
|
# newline automatically
|
|
if {[string index $script end] == "\n"} {
|
|
set script [string replace $script end end]
|
|
}
|
|
dumpputs $method $dest $script
|
|
dumpputs $method $dest "\}"
|
|
dumpputs $method $dest ""
|
|
}
|
|
}
|
|
|
|
dumpGlobalOptions $method $dest
|
|
|
|
# session options
|
|
dumpputs $method $dest "option session \{"
|
|
foreach kv [getSessionOptionsList] { dumpputs $method $dest " $kv" }
|
|
dumpputs $method $dest "\}"
|
|
dumpputs $method $dest ""
|
|
}
|
|
|
|
proc dumpGlobalOptions { method dest } {
|
|
global showIfNames showNodeLabels showLinkLabels
|
|
global showIfIPaddrs showIfIPv6addrs
|
|
global showBkgImage showGrid showAnnotations
|
|
global showAPI
|
|
global g_view_locked
|
|
global g_traffic_start_opt
|
|
global mac_addr_start
|
|
|
|
dumpputs $method $dest "option global \{"
|
|
if {$showIfNames == 0} {
|
|
dumpputs $method $dest " interface_names no"
|
|
} else {
|
|
dumpputs $method $dest " interface_names yes" }
|
|
if {$showIfIPaddrs == 0} {
|
|
dumpputs $method $dest " ip_addresses no"
|
|
} else {
|
|
dumpputs $method $dest " ip_addresses yes" }
|
|
if {$showIfIPv6addrs == 0} {
|
|
dumpputs $method $dest " ipv6_addresses no"
|
|
} else {
|
|
dumpputs $method $dest " ipv6_addresses yes" }
|
|
if {$showNodeLabels == 0} {
|
|
dumpputs $method $dest " node_labels no"
|
|
} else {
|
|
dumpputs $method $dest " node_labels yes" }
|
|
if {$showLinkLabels == 0} {
|
|
dumpputs $method $dest " link_labels no"
|
|
} else {
|
|
dumpputs $method $dest " link_labels yes" }
|
|
if {$showAPI == 0} {
|
|
dumpputs $method $dest " show_api no"
|
|
} else {
|
|
dumpputs $method $dest " show_api yes" }
|
|
if {$showBkgImage == 0} {
|
|
dumpputs $method $dest " background_images no"
|
|
} else {
|
|
dumpputs $method $dest " background_images yes" }
|
|
if {$showAnnotations == 0} {
|
|
dumpputs $method $dest " annotations no"
|
|
} else {
|
|
dumpputs $method $dest " annotations yes" }
|
|
if {$showGrid == 0} {
|
|
dumpputs $method $dest " grid no"
|
|
} else {
|
|
dumpputs $method $dest " grid yes" }
|
|
if {$g_view_locked == 1} {
|
|
dumpputs $method $dest " locked yes" }
|
|
if { [info exists g_traffic_start_opt] } {
|
|
dumpputs $method $dest " traffic_start $g_traffic_start_opt"
|
|
}
|
|
if { [info exists mac_addr_start] && $mac_addr_start > 0 } {
|
|
dumpputs $method $dest " mac_address_start $mac_addr_start"
|
|
}
|
|
dumpputs $method $dest "\}"
|
|
dumpputs $method $dest ""
|
|
}
|
|
|
|
# get the global options into a list of key=value pairs
|
|
proc getGlobalOptionList {} {
|
|
global tmp
|
|
set tmp ""
|
|
dumpGlobalOptions string tmp ;# put "options global {items}" into tmp
|
|
set items [lindex $tmp 2]
|
|
return [listToKeyValues $items]
|
|
}
|
|
|
|
proc setGlobalOption { field value } {
|
|
global showIfNames showNodeLabels showLinkLabels
|
|
global showIfIPaddrs showIfIPv6addrs
|
|
global showBkgImage showGrid showAnnotations
|
|
global showAPI
|
|
global mac_addr_start
|
|
global g_traffic_start_opt
|
|
global g_view_locked
|
|
|
|
switch -exact -- $field {
|
|
interface_names {
|
|
if { $value == "no" } {
|
|
set showIfNames 0
|
|
} elseif { $value == "yes" } {
|
|
set showIfNames 1
|
|
}
|
|
}
|
|
ip_addresses {
|
|
if { $value == "no" } {
|
|
set showIfIPaddrs 0
|
|
} elseif { $value == "yes" } {
|
|
set showIfIPaddrs 1
|
|
}
|
|
}
|
|
ipv6_addresses {
|
|
if { $value == "no" } {
|
|
set showIfIPv6addrs 0
|
|
} elseif { $value == "yes" } {
|
|
set showIfIPv6addrs 1
|
|
}
|
|
}
|
|
node_labels {
|
|
if { $value == "no" } {
|
|
set showNodeLabels 0
|
|
} elseif { $value == "yes" } {
|
|
set showNodeLabels 1
|
|
}
|
|
}
|
|
link_labels {
|
|
if { $value == "no" } {
|
|
set showLinkLabels 0
|
|
} elseif { $value == "yes" } {
|
|
set showLinkLabels 1
|
|
}
|
|
}
|
|
show_api {
|
|
if { $value == "no" } {
|
|
set showAPI 0
|
|
} elseif { $value == "yes" } {
|
|
set showAPI 1
|
|
}
|
|
}
|
|
background_images {
|
|
if { $value == "no" } {
|
|
set showBkgImage 0
|
|
} elseif { $value == "yes" } {
|
|
set showBkgImage 1
|
|
}
|
|
}
|
|
annotations {
|
|
if { $value == "no" } {
|
|
set showAnnotations 0
|
|
} elseif { $value == "yes" } {
|
|
set showAnnotations 1
|
|
}
|
|
}
|
|
grid {
|
|
if { $value == "no" } {
|
|
set showGrid 0
|
|
} elseif { $value == "yes" } {
|
|
set showGrid 1
|
|
}
|
|
}
|
|
locked {
|
|
if { $value == "yes" } {
|
|
set g_view_locked 1
|
|
} else {
|
|
set g_view_locked 0
|
|
}
|
|
}
|
|
mac_address_start {
|
|
set mac_addr_start $value
|
|
}
|
|
traffic_start {
|
|
set g_traffic_start_opt $value
|
|
}
|
|
}
|
|
}
|
|
|
|
# reset global vars when opening a new file
|
|
proc cleanupGUIState {} {
|
|
global node_list link_list plot_list canvas_list annotation_list
|
|
global mac_addr_start g_comments
|
|
global g_traffic_flows g_traffic_start_opt g_hook_scripts
|
|
global g_view_locked
|
|
|
|
set node_list {}
|
|
set link_list {}
|
|
set annotation_list {}
|
|
set plot_list {}
|
|
set canvas_list {}
|
|
set g_traffic_flows ""
|
|
set g_traffic_start_opt 0
|
|
set g_hook_scripts ""
|
|
set g_comments ""
|
|
set g_view_locked 0
|
|
resetSessionOptions
|
|
}
|
|
|
|
#****f* nodecfg.tcl/loadCfg
|
|
# NAME
|
|
# loadCfg -- loads the current configuration.
|
|
# SYNOPSIS
|
|
# loadCfg $cfg
|
|
# FUNCTION
|
|
# Loads the configuration written in the cfg string to a current
|
|
# configuration.
|
|
# INPUTS
|
|
# * cfg -- string containing the new working configuration.
|
|
#****
|
|
|
|
proc loadCfg { cfg } {
|
|
global node_list plot_list link_list canvas_list annotation_list
|
|
global g_traffic_flows g_traffic_start_opt g_hook_scripts
|
|
global g_view_locked
|
|
global g_comments
|
|
|
|
# maximum coordinates
|
|
set maxX 0
|
|
set maxY 0
|
|
set do_upgrade [upgradeOldConfig cfg]
|
|
if { $do_upgrade == "no"} { return }
|
|
|
|
# Cleanup first
|
|
cleanupGUIState
|
|
set class ""
|
|
set object ""
|
|
foreach entry $cfg {
|
|
if {"$class" == ""} {
|
|
set class $entry
|
|
continue
|
|
} elseif {"$object" == ""} {
|
|
set object $entry
|
|
if {"$class" == "node"} {
|
|
lappend node_list $object
|
|
} elseif {"$class" == "link"} {
|
|
lappend link_list $object
|
|
} elseif {"$class" == "canvas"} {
|
|
lappend canvas_list $object
|
|
} elseif {"$class" == "plot"} {
|
|
lappend plot_list $object
|
|
} elseif {"$class" == "option"} {
|
|
# do nothing
|
|
} elseif {"$class" == "traffic"} { ;# save traffic flows
|
|
set g_traffic_flows [split [string trim $object] "\n"]
|
|
set class ""; set object ""; continue
|
|
} elseif {"$class" == "script"} {
|
|
# global_script (old config) becomes a runtime hook
|
|
set name "runtime_hook.sh"
|
|
set script [string trim $object]
|
|
lappend g_hook_scripts [list $name 4 $script] ;# 4=RUNTIME_STATE
|
|
set class ""; set object ""; continue
|
|
} elseif {"$class" == "hook"} {
|
|
continue
|
|
} elseif {"$class" == "comments"} {
|
|
set g_comments [string trim $object]
|
|
set class ""; set object ""; continue
|
|
} elseif {"$class" == "annotation"} {
|
|
lappend annotation_list $object
|
|
} else {
|
|
puts "configuration parsing error: unknown object class $class"
|
|
#exit 1
|
|
}
|
|
# create an empty global variable named object for most objects
|
|
global $object
|
|
set $object {}
|
|
continue
|
|
} else {
|
|
set line [concat $entry]
|
|
# uses 'key=value' instead of 'key value'
|
|
if { $object == "session" } {
|
|
# 'key=value', values with space needs quoting 'key={space val}'
|
|
setSessionOptions "" [split $line "\n"]
|
|
set class ""
|
|
set object ""
|
|
continue
|
|
}
|
|
# extracts "field { value }" elements from line
|
|
if { [catch { set tmp [llength $line] } e] } {
|
|
puts "*** Error with line ('$e'):\n$line"
|
|
puts "*** Line will be skipped. This is a Tcl limitation, "
|
|
puts "*** consider using XML or fixing with whitespace."
|
|
continue
|
|
}
|
|
while {[llength $line] >= 2} {
|
|
set field [lindex $line 0]
|
|
if {"$field" == ""} {
|
|
set line [lreplace $line 0 0]
|
|
continue
|
|
}
|
|
|
|
# consume first two list elements from line
|
|
set value [lindex $line 1]
|
|
set line [lreplace $line 0 1]
|
|
|
|
if {"$class" == "node"} {
|
|
switch -exact -- $field {
|
|
type {
|
|
lappend $object "type $value"
|
|
}
|
|
mirror {
|
|
lappend $object "mirror $value"
|
|
}
|
|
model {
|
|
lappend $object "model $value"
|
|
}
|
|
cpu {
|
|
lappend $object "cpu {$value}"
|
|
}
|
|
interface-peer {
|
|
lappend $object "interface-peer {$value}"
|
|
}
|
|
network-config {
|
|
set cfg ""
|
|
foreach zline [split $value {
|
|
}] {
|
|
if { [string index "$zline" 0] == " " } {
|
|
set zline [string replace "$zline" 0 0]
|
|
}
|
|
lappend cfg $zline
|
|
}
|
|
set cfg [lrange $cfg 1 [expr {[llength $cfg] - 2}]]
|
|
lappend $object "network-config {$cfg}"
|
|
}
|
|
custom-enabled {
|
|
lappend $object "custom-enabled $value"
|
|
}
|
|
custom-command {
|
|
lappend $object "custom-command {$value}"
|
|
}
|
|
custom-config {
|
|
set cfg ""
|
|
set have_config 0
|
|
set ccfg {}
|
|
foreach zline [split $value "\n"] {
|
|
if { [string index "$zline" 0] == \
|
|
" " } {
|
|
# remove leading tab character
|
|
set zline [string replace "$zline" 0 0]
|
|
}
|
|
|
|
# flag for config lines
|
|
if { $zline == "config \{" } {
|
|
set have_config 1
|
|
# collect custom config lines into list
|
|
} elseif { $have_config == 1 } {
|
|
lappend ccfg $zline
|
|
# add non-config lines
|
|
} else {
|
|
lappend cfg $zline
|
|
}
|
|
}
|
|
# chop off last brace in config { } block and add it
|
|
if { $have_config } {
|
|
set ccfg [lrange $ccfg 0 \
|
|
[expr {[llength $ccfg] - 3}]]
|
|
lappend cfg [list config $ccfg]
|
|
}
|
|
#set cfg [lrange $cfg 1 [expr {[llength $cfg] - 2}]]
|
|
lappend $object "custom-config {$cfg}"
|
|
}
|
|
ipsec-enabled {
|
|
lappend $object "ipsec-enabled $value"
|
|
}
|
|
ipsec-config {
|
|
set cfg ""
|
|
|
|
foreach zline [split $value {
|
|
}] {
|
|
if { [string index "$zline" 0] == " " } {
|
|
set zline [string replace "$zline" 0 0]
|
|
}
|
|
lappend cfg $zline
|
|
}
|
|
set cfg [lrange $cfg 1 [expr {[llength $cfg] - 2}]]
|
|
lappend $object "ipsec-config {$cfg}"
|
|
}
|
|
iconcoords {
|
|
checkMaxCoords $value maxX maxY
|
|
lappend $object "iconcoords {$value}"
|
|
}
|
|
labelcoords {
|
|
checkMaxCoords $value maxX maxY
|
|
lappend $object "labelcoords {$value}"
|
|
}
|
|
canvas {
|
|
lappend $object "canvas $value"
|
|
}
|
|
hidden {
|
|
lappend $object "hidden $value"
|
|
}
|
|
/* {
|
|
set comment "$field $value"
|
|
foreach c $line {
|
|
lappend comment $c
|
|
# consume one element from line
|
|
set line [lreplace $line 0 0]
|
|
if { $c == "*/" } { break }
|
|
}
|
|
lappend $object "$comment"
|
|
}
|
|
|
|
custom-pre-config-commands {
|
|
# Boeing - custom pre config commands
|
|
set cfg ""
|
|
foreach zline [split $value {
|
|
}] {
|
|
if { [string index "$zline" 0] == " " } {
|
|
set zline [string replace "$zline" 0 0]
|
|
}
|
|
lappend cfg $zline
|
|
}
|
|
set cfg [lrange $cfg 1 [expr [llength $cfg] - 2]]
|
|
lappend $object "custom-pre-config-commands {$cfg}"
|
|
}
|
|
custom-post-config-commands {
|
|
# Boeing - custom post config commands
|
|
set cfg ""
|
|
foreach zline [split $value {
|
|
}] {
|
|
if { [string index "$zline" 0] == " " } {
|
|
set zline [string replace "$zline" 0 0]
|
|
}
|
|
lappend cfg $zline
|
|
}
|
|
set cfg [lrange $cfg 1 [expr [llength $cfg] - 2]]
|
|
lappend $object "custom-post-config-commands {$cfg}"
|
|
}
|
|
custom-image {
|
|
# Boeing - custom-image
|
|
lappend $object "custom-image $value"
|
|
}
|
|
ine-config {
|
|
# Boeing - INE
|
|
set cfg ""
|
|
foreach zline [split $value {
|
|
}] {
|
|
if { [string index "$zline" 0] == " " } {
|
|
set zline [string replace "$zline" 0 0]
|
|
}
|
|
lappend cfg $zline
|
|
}
|
|
set cfg [lrange $cfg 1 [expr [llength $cfg] - 2]]
|
|
lappend $object "ine-config {$cfg}"
|
|
}
|
|
tunnel-peer {
|
|
# Boeing - Span tunnels
|
|
lappend $object "tunnel-peer {$value}"
|
|
}
|
|
range {
|
|
# Boeing - WLAN range
|
|
lappend $object "range $value"
|
|
}
|
|
bandwidth {
|
|
# Boeing - WLAN bandwidth
|
|
lappend $object "bandwidth $value"
|
|
}
|
|
cli-enabled {
|
|
puts "Warning: cli-enabled setting is deprecated"
|
|
}
|
|
delay {
|
|
# Boeing - WLAN delay
|
|
lappend $object "delay $value"
|
|
}
|
|
ber {
|
|
# Boeing - WLAN BER
|
|
lappend $object "ber $value"
|
|
}
|
|
location {
|
|
# Boeing - node location
|
|
lappend $object "location $value"
|
|
}
|
|
os {
|
|
# Boeing - node OS
|
|
# just ignore it, set at runtime
|
|
}
|
|
services {
|
|
lappend $object "services {$value}"
|
|
}
|
|
|
|
default {
|
|
# Boeing - added warning
|
|
puts -nonewline "config file warning: unknown confi"
|
|
puts "guration item '$field' ignored for $object"
|
|
}
|
|
}
|
|
} elseif {"$class" == "plot"} {
|
|
switch -exact -- $field {
|
|
name {
|
|
lappend $object "name $value"
|
|
}
|
|
height {
|
|
lappend $object "height $value"
|
|
}
|
|
width {
|
|
lappend $object "width $value"
|
|
}
|
|
x {
|
|
lappend $object "x $value"
|
|
}
|
|
y {
|
|
lappend $object "y $value"
|
|
}
|
|
color {
|
|
lappend $object "color $value"
|
|
}
|
|
}
|
|
} elseif {"$class" == "link"} {
|
|
switch -exact -- $field {
|
|
nodes {
|
|
lappend $object "nodes {$value}"
|
|
}
|
|
mirror {
|
|
lappend $object "mirror $value"
|
|
}
|
|
bandwidth -
|
|
delay -
|
|
ber -
|
|
duplicate -
|
|
jitter {
|
|
if { [llength $value] > 1 } { ;# down/up-stream
|
|
lappend $object "$field {$value}"
|
|
} else {
|
|
lappend $object "$field $value"
|
|
}
|
|
}
|
|
color {
|
|
lappend $object "color $value"
|
|
}
|
|
width {
|
|
lappend $object "width $value"
|
|
}
|
|
default {
|
|
# this enables opaque data to be stored along with
|
|
# each link (any key is stored)
|
|
lappend $object "$field $value"
|
|
# Boeing - added warning
|
|
#puts -nonewline "config file warning: unknown conf"
|
|
#puts "iguration item '$field' ignored for $object"
|
|
}
|
|
}
|
|
} elseif {"$class" == "canvas"} {
|
|
switch -exact -- $field {
|
|
name {
|
|
lappend $object "name {$value}"
|
|
}
|
|
size {
|
|
lappend $object "size {$value}"
|
|
}
|
|
bkgImage {
|
|
lappend $object "wallpaper {$value}"
|
|
}
|
|
wallpaper {
|
|
lappend $object "wallpaper {$value}"
|
|
}
|
|
wallpaper-style {
|
|
lappend $object "wallpaper-style {$value}"
|
|
}
|
|
scale {
|
|
lappend $object "scale {$value}"
|
|
}
|
|
refpt {
|
|
lappend $object "refpt {$value}"
|
|
}
|
|
}
|
|
} elseif {"$class" == "option"} {
|
|
setGlobalOption $field $value
|
|
} elseif {"$class" == "annotation"} {
|
|
switch -exact -- $field {
|
|
type {
|
|
lappend $object "type $value"
|
|
}
|
|
iconcoords {
|
|
lappend $object "iconcoords {$value}"
|
|
}
|
|
color {
|
|
lappend $object "color $value"
|
|
}
|
|
border {
|
|
lappend $object "border $value"
|
|
}
|
|
label {
|
|
lappend $object "label {$value}"
|
|
}
|
|
labelcolor {
|
|
lappend $object "labelcolor $value"
|
|
}
|
|
size {
|
|
lappend $object "size $value"
|
|
}
|
|
canvas {
|
|
lappend $object "canvas $value"
|
|
}
|
|
font {
|
|
lappend $object "font {$value}"
|
|
}
|
|
fontfamily {
|
|
lappend $object "fontfamily {$value}"
|
|
}
|
|
fontsize {
|
|
lappend $object "fontsize {$value}"
|
|
}
|
|
effects {
|
|
lappend $object "effects {$value}"
|
|
}
|
|
width {
|
|
lappend $object "width $value"
|
|
}
|
|
rad {
|
|
lappend $object "rad $value"
|
|
}
|
|
} ;# end switch
|
|
} elseif {"$class" == "hook"} {
|
|
set state_name [split $object :]
|
|
if { [llength $state_name] != 2 } {
|
|
puts "invalid hook in config file"
|
|
continue
|
|
}
|
|
set state [lindex $state_name 0]
|
|
set name [lindex $state_name 1]
|
|
set lines [split $entry "\n"]
|
|
set lines [lreplace $lines 0 0] ;# chop extra newline
|
|
set lines [join $lines "\n"]
|
|
set hook [list $name $state $lines]
|
|
lappend g_hook_scripts $hook
|
|
set line "" ;# exit this while loop
|
|
} ;#endif class
|
|
}
|
|
}
|
|
set class ""
|
|
set object ""
|
|
}
|
|
|
|
#
|
|
# Hack for comaptibility with old format files (no canvases)
|
|
#
|
|
if { $canvas_list == "" } {
|
|
set curcanvas [newCanvas ""]
|
|
foreach node $node_list {
|
|
setNodeCanvas $node $curcanvas
|
|
}
|
|
}
|
|
|
|
|
|
# auto resize canvas
|
|
set curcanvas [lindex $canvas_list 0]
|
|
set newX 0
|
|
set newY 0
|
|
if { $maxX > [lindex [getCanvasSize $curcanvas] 0] } {
|
|
set newX [expr {$maxX + 50}]
|
|
}
|
|
if { $maxY > [lindex [getCanvasSize $curcanvas] 1] } {
|
|
set newY [expr {$maxY + 50}]
|
|
}
|
|
if { $newX > 0 || $newY > 0 } {
|
|
if { $newX == 0 } { set newX [lindex [getCanvasSize $curcanvas] 0] }
|
|
if { $newY == 0 } { set newY [lindex [getCanvasSize $curcanvas] 1] }
|
|
setCanvasSize $curcanvas $newX $newY
|
|
}
|
|
|
|
# extra upgrade steps
|
|
if { $do_upgrade == "yes" } {
|
|
upgradeNetworkConfigToServices
|
|
}
|
|
upgradeConfigRemoveNode0
|
|
upgradeConfigServices
|
|
upgradeWlanConfigs
|
|
}
|
|
|
|
#****f* nodecfg.tcl/newObjectId
|
|
# NAME
|
|
# newObjectId -- new object Id
|
|
# SYNOPSIS
|
|
# set obj_id [newObjectId $type]
|
|
# FUNCTION
|
|
# Returns the Id for a new object of the defined type. Supported types
|
|
# are node, link and canvas. The Id is in the form $mark$number. $mark is the
|
|
# first letter of the given type and $number is the first available number to
|
|
# that can be used for id.
|
|
# INPUTS
|
|
# * type -- the type of the new object. Can be node, link or canvas.
|
|
# RESULT
|
|
# * obj_id -- object Id in the form $mark$number. $mark is the
|
|
# first letter of the given type and $number is the first available number to
|
|
# that can be used for id.
|
|
#****
|
|
|
|
proc newObjectId { type } {
|
|
global node_list link_list annotation_list canvas_list
|
|
|
|
set mark [string range [set type] 0 0]
|
|
set id 1 ;# start numbering at 1, not 0
|
|
while {[lsearch [set [set type]_list] "$mark$id"] != -1} {
|
|
incr id
|
|
}
|
|
return $mark$id
|
|
}
|
|
|
|
|
|
|
|
# Boeing: pick a new link id for temporary newlinks
|
|
proc newlinkId { } {
|
|
global link_list
|
|
set id [newObjectId link]
|
|
set mark "l"
|
|
set id 0
|
|
|
|
# alllinks contains a list of all existing and new links
|
|
set alllinks $link_list
|
|
foreach newlink [.c find withtag "newlink"] {
|
|
set newlinkname [lindex [.c gettags $newlink] 1]
|
|
lappend alllinks $newlinkname
|
|
}
|
|
|
|
while {[lsearch $alllinks "$mark$id"] != -1 } {
|
|
incr id
|
|
}
|
|
return $mark$id
|
|
}
|
|
|
|
# Boeing: helper fn to determine canvas size during load
|
|
proc checkMaxCoords { str maxXp maxYp } {
|
|
upvar 1 $maxXp maxX
|
|
upvar 1 $maxYp maxY
|
|
set x [lindex $str 0]
|
|
set y [lindex $str 1]
|
|
if { $x > $maxX } {
|
|
set maxX $x
|
|
}
|
|
if { $y > $maxY } {
|
|
set maxY $y
|
|
}
|
|
if { [llength $str] == 4 } {
|
|
set x [lindex $str 2]
|
|
set y [lindex $str 3]
|
|
if { $x > $maxX } {
|
|
set maxX $x
|
|
}
|
|
if { $y > $maxY } {
|
|
set maxY $y
|
|
}
|
|
}
|
|
}
|
|
|
|
# Boeing: pick a router for OSPF
|
|
proc newRouterId { type node } {
|
|
set mark [string range [set type] 0 0]
|
|
for { set id 0 } { $node != "$mark$id" } { incr id } {
|
|
}
|
|
return "0.0.0.${id}"
|
|
}
|
|
# end Boeing
|
|
|
|
# Boeing: load servers.conf file into exec_servers array
|
|
proc loadServersConf { } {
|
|
global CONFDIR exec_servers DEFAULT_API_PORT
|
|
set confname "$CONFDIR/servers.conf"
|
|
if { [catch { set f [open "$confname" r] } ] } {
|
|
puts "Creating a default $confname"
|
|
if { [catch { set f [open "$confname" w+] } ] } {
|
|
puts "***Warning: could not create a default $confname file."
|
|
return
|
|
}
|
|
puts $f "core1 192.168.0.2 $DEFAULT_API_PORT"
|
|
puts $f "core2 192.168.0.3 $DEFAULT_API_PORT"
|
|
close $f
|
|
if { [catch { set f [open "$confname" r] } ] } {
|
|
return
|
|
}
|
|
}
|
|
|
|
array unset exec_servers
|
|
|
|
while { [ gets $f line ] >= 0 } {
|
|
if { [string range $line 0 0] == "#" } { continue } ;# skip comments
|
|
set l [split $line] ;# parse fields separated by whitespace
|
|
set name [lindex $l 0]
|
|
set ip [lindex $l 1]
|
|
set port [lindex $l 2]
|
|
set sock -1
|
|
if { $name == "" } { continue } ;# blank name
|
|
# load array of servers
|
|
array set exec_servers [list $name [list $ip $port $sock]]
|
|
}
|
|
close $f
|
|
}
|
|
# end Boeing
|
|
|
|
# Boeing: write servers.conf file from exec_servers array
|
|
proc writeServersConf { } {
|
|
global CONFDIR exec_servers
|
|
set confname "$CONFDIR/servers.conf"
|
|
if { [catch { set f [open "$confname" w] } ] } {
|
|
puts "***Warning: could not write servers file: $confname"
|
|
return
|
|
}
|
|
|
|
set header "# servers.conf: list of CORE emulation servers for running"
|
|
set header "$header remotely."
|
|
puts $f $header
|
|
foreach server [lsort -dictionary [array names exec_servers]] {
|
|
set ip [lindex $exec_servers($server) 0]
|
|
set port [lindex $exec_servers($server) 1]
|
|
puts $f "$server $ip $port"
|
|
}
|
|
close $f
|
|
}
|
|
# end Boeing
|
|
|
|
# display the preferences dialog
|
|
proc popupPrefs {} {
|
|
global EDITORS TERMS
|
|
|
|
set wi .core_prefs
|
|
catch { destroy $wi }
|
|
toplevel $wi
|
|
|
|
wm transient $wi .
|
|
wm resizable $wi 0 0
|
|
wm title $wi "Preferences"
|
|
|
|
global g_prefs g_prefs_old
|
|
array set g_prefs_old [array get g_prefs]
|
|
|
|
#
|
|
# Paths
|
|
#
|
|
labelframe $wi.dirs -borderwidth 4 -text "Paths" -relief raised
|
|
frame $wi.dirs.conf
|
|
label $wi.dirs.conf.label -text "Default configuration file path:"
|
|
entry $wi.dirs.conf.entry -bg white -width 40 \
|
|
-textvariable g_prefs(default_conf_path)
|
|
pack $wi.dirs.conf.label $wi.dirs.conf.entry -side left
|
|
pack $wi.dirs.conf -side top -anchor w -padx 4 -pady 4
|
|
|
|
frame $wi.dirs.mru
|
|
label $wi.dirs.mru.label -text "Number of recent files to remember:"
|
|
entry $wi.dirs.mru.num -bg white -width 3 \
|
|
-textvariable g_prefs(num_recent)
|
|
button $wi.dirs.mru.clear -text "Clear recent files" \
|
|
-command "addFileToMrulist \"\""
|
|
pack $wi.dirs.mru.label $wi.dirs.mru.num $wi.dirs.mru.clear -side left
|
|
pack $wi.dirs.mru -side top -anchor w -padx 4 -pady 4
|
|
|
|
pack $wi.dirs -side top -fill x
|
|
|
|
#
|
|
# Window
|
|
#
|
|
labelframe $wi.win -borderwidth 4 -text "GUI Window" -relief raised
|
|
frame $wi.win.win
|
|
checkbutton $wi.win.win.savepos -text "remember window position" \
|
|
-variable g_prefs(gui_save_pos)
|
|
checkbutton $wi.win.win.savesiz -text "remember window size" \
|
|
-variable g_prefs(gui_save_size)
|
|
pack $wi.win.win.savepos $wi.win.win.savesiz -side left -anchor w -padx 4
|
|
pack $wi.win.win -side top -anchor w -padx 4 -pady 4
|
|
|
|
frame $wi.win.a
|
|
checkbutton $wi.win.a.snaptogrid -text "snap to grid" \
|
|
-variable g_prefs(gui_snap_grid)
|
|
checkbutton $wi.win.a.showtooltips -text "show tooltips" \
|
|
-variable g_prefs(gui_show_tooltips)
|
|
pack $wi.win.a.snaptogrid $wi.win.a.showtooltips \
|
|
-side left -anchor w -padx 4
|
|
pack $wi.win.a -side top -anchor w -padx 4 -pady 4
|
|
|
|
frame $wi.win.canv
|
|
label $wi.win.canv.label -text "Default canvas size:"
|
|
entry $wi.win.canv.x -bg white -width 5 -textvariable g_prefs(gui_canvas_x)
|
|
entry $wi.win.canv.y -bg white -width 5 -textvariable g_prefs(gui_canvas_y)
|
|
label $wi.win.canv.label2 -text "Default # of canvases:"
|
|
entry $wi.win.canv.num -bg white -width 5 \
|
|
-textvariable g_prefs(gui_num_canvases)
|
|
pack $wi.win.canv.label $wi.win.canv.x $wi.win.canv.y \
|
|
$wi.win.canv.label2 $wi.win.canv.num \
|
|
-side left -anchor w -padx 4
|
|
pack $wi.win.canv -side top -anchor w -padx 4 -pady 4
|
|
pack $wi.win -side top -fill x
|
|
|
|
#
|
|
# Programs
|
|
#
|
|
labelframe $wi.pr -borderwidth 4 -text "Programs" -relief raised
|
|
|
|
frame $wi.pr.editor
|
|
label $wi.pr.editor.label -text "Text editor:"
|
|
set editors [linsert $EDITORS 0 "EDITOR"]
|
|
ttk::combobox $wi.pr.editor.combo -width 10 -exportselection 0 \
|
|
-values $editors -textvariable g_prefs(gui_text_editor)
|
|
label $wi.pr.editor.label2 -text "Terminal program:"
|
|
set terms [linsert $TERMS 0 "TERM"]
|
|
ttk::combobox $wi.pr.editor.combo2 -width 20 -exportselection 0 \
|
|
-values $terms -textvariable g_prefs(gui_term_prog)
|
|
pack $wi.pr.editor.label $wi.pr.editor.combo -padx 4 -pady 4 -side left
|
|
pack $wi.pr.editor.label2 $wi.pr.editor.combo2 -padx 4 -pady 4 -side left
|
|
pack $wi.pr.editor -side top -anchor w -padx 4 -pady 4
|
|
|
|
frame $wi.pr.3d
|
|
label $wi.pr.3d.label -text "3D GUI command:"
|
|
entry $wi.pr.3d.entry -bg white -width 40 -textvariable g_prefs(gui_3d_path)
|
|
pack $wi.pr.3d.label $wi.pr.3d.entry -side left -padx 4 -pady 4
|
|
pack $wi.pr.3d -side top -anchor w -padx 4 -pady 4
|
|
|
|
pack $wi.pr -side top -fill x
|
|
|
|
#
|
|
# Buttons at the bottom
|
|
#
|
|
frame $wi.bot -borderwidth 0
|
|
button $wi.bot.apply -text "Save" -command "savePrefsFile; destroy $wi"
|
|
button $wi.bot.defaults -text "Load defaults" -command initDefaultPrefs
|
|
button $wi.bot.cancel -text "Cancel" -command {
|
|
global g_prefs g_prefs_old
|
|
array set g_prefs [array get g_prefs_old]
|
|
destroy .core_prefs
|
|
}
|
|
pack $wi.bot.cancel $wi.bot.defaults $wi.bot.apply -side right
|
|
pack $wi.bot -side bottom -fill x
|
|
after 100 {
|
|
catch { grab .core_prefs }
|
|
}
|
|
}
|
|
|
|
# initialize preferences array with default values
|
|
proc initDefaultPrefs {} {
|
|
global g_prefs CONFDIR SBINDIR DEFAULT_REFPT tcl_platform
|
|
|
|
# variable expansions must be done here
|
|
array set g_prefs [list default_conf_path "$CONFDIR/configs"]
|
|
array set g_prefs [list gui_canvas_refpt "$DEFAULT_REFPT"]
|
|
set shell "bash"
|
|
array set g_prefs [list shell $shell]
|
|
array set g_prefs [list gui_text_editor [get_text_editor true]]
|
|
array set g_prefs [list gui_term_prog [get_term_prog true]]
|
|
setDefaultAddrs ipv4
|
|
setDefaultAddrs ipv6
|
|
# preferences will be reordered alphabetically
|
|
array set g_prefs {
|
|
num_recent 4
|
|
log_path "/tmp/core_logs"
|
|
gui_save_pos 0
|
|
gui_save_size 0
|
|
gui_snap_grid 0
|
|
gui_show_tooltips 1
|
|
gui_canvas_x 1000
|
|
gui_canvas_y 750
|
|
gui_canvas_scale 150.0
|
|
gui_num_canvases 1
|
|
gui_3d_path "/usr/local/bin/sdt3d.sh"
|
|
}
|
|
# add new preferences above; keep this at the end of the file
|
|
}
|
|
|
|
|