initial pass at removing bsd and code related to using bsd nodes

This commit is contained in:
Blake J. Harnden 2018-03-07 12:54:19 -08:00
parent 4858151d7c
commit bc1e3e70c9
62 changed files with 720 additions and 18008 deletions

View file

@ -31,7 +31,6 @@ EXTRA_DIST = bootstrap.sh LICENSE \
README-Xen Changelog kernel \ README-Xen Changelog kernel \
python-prefix.py revision.sh \ python-prefix.py revision.sh \
.version .version.date \ .version .version.date \
packaging/bsd \
packaging/deb/compat \ packaging/deb/compat \
packaging/deb/copyright \ packaging/deb/copyright \
packaging/deb/changelog \ packaging/deb/changelog \
@ -55,7 +54,6 @@ MAINTAINERCLEANFILES = \
# don't include svn dirs in source tarball # don't include svn dirs in source tarball
dist-hook: dist-hook:
rm -rf `find $(distdir)/kernel -name .svn` rm -rf `find $(distdir)/kernel -name .svn`
rm -rf $(distdir)/packaging/bsd/.svn
# build a source RPM # build a source RPM
.PHONY: rpm .PHONY: rpm

View file

@ -7,16 +7,17 @@
# Bootstrap the autoconf system. # Bootstrap the autoconf system.
# #
if [ x$1 = x ]; then # PASS # PASS
if [ x$1 = x ]; then
echo "Bootstrapping the autoconf system..." echo "Bootstrapping the autoconf system..."
# echo " These autotools programs should be installed for this script to work:"
# echo " aclocal, libtoolize, autoheader, automake, autoconf"
echo "(Messages below about copying and installing files are normal.)" echo "(Messages below about copying and installing files are normal.)"
elif [ x$1 = xclean ]; then # clean - take out the trash # clean - take out the trash
elif [ x$1 = xclean ]; then
echo "Cleaning up the autoconf mess..." echo "Cleaning up the autoconf mess..."
rm -rf autom4te.cache config BSDmakefile rm -rf autom4te.cache config
exit 0; exit 0;
else # help text # help text
else
echo "usage: $0 [clean]" echo "usage: $0 [clean]"
echo -n " Use this script to bootstrap the autoconf build system prior to " echo -n " Use this script to bootstrap the autoconf build system prior to "
echo "running the " echo "running the "
@ -29,15 +30,6 @@ if ! [ -d "config" ]; then
mkdir config mkdir config
fi fi
# on FreeBSD, discourage use of make
UNAME=`uname`
if [ x${UNAME} = xFreeBSD ]; then
echo "all:" > BSDmakefile
echo ' @echo "Please use GNU make instead by typing:"' >> BSDmakefile
echo ' @echo " gmake"' >> BSDmakefile
echo ' @echo ""' >> BSDmakefile
fi
# bootstrapping # bootstrapping
echo "(1/4) Running aclocal..." && aclocal -I config \ echo "(1/4) Running aclocal..." && aclocal -I config \
&& echo "(2/4) Running autoheader..." && autoheader \ && echo "(2/4) Running autoheader..." && autoheader \

View file

@ -104,7 +104,6 @@ AC_ARG_ENABLE([daemon],
AC_SUBST(enable_daemon) AC_SUBST(enable_daemon)
if test "x$enable_daemon" = "xno"; then if test "x$enable_daemon" = "xno"; then
want_python=no want_python=no
want_bsd=no
want_linux_netns=no want_linux_netns=no
fi fi
@ -211,18 +210,9 @@ if test "x$enable_daemon" = "xyes" ; then
fi fi
# Host-specific detection # Host-specific detection
want_linux_netns=no want_linux_netns=yes
want_bsd=no
if test `uname -s` = "FreeBSD"; then
want_bsd=yes
AC_CHECK_PROGS(gmake)
# FreeBSD fix for linking libev port below
CFLAGS="$CFLAGS -L/usr/local/lib"
else
want_linux_netns=yes
fi
if test "x$want_python" = "xno"; then if test "x$want_python" = "xno"; then
want_bsd=no
want_linux_netns=no want_linux_netns=no
fi fi
@ -283,17 +273,6 @@ if test "x$want_linux_netns" = "xyes"; then
AC_MSG_ERROR([Could not locate tc (from iproute package).]) AC_MSG_ERROR([Could not locate tc (from iproute package).])
fi fi
fi fi
if test "x$want_bsd" = "xyes"; then
if test "x$ifconfig_path" = "xno" ; then
AC_MSG_ERROR([Could not locate the 'ifconfig' utility.])
fi
if test "x$ngctl_path" = "xno" ; then
AC_MSG_ERROR([Could not locate the 'ngctl' utility.])
fi
if test "x$vimage_path" = "xno" ; then
AC_MSG_ERROR([Could not locate the 'vimage' utility.])
fi
fi
AC_ARG_WITH([startup], AC_ARG_WITH([startup],
[AS_HELP_STRING([--with-startup=option], [AS_HELP_STRING([--with-startup=option],
@ -306,7 +285,6 @@ AC_MSG_RESULT([using startup option $with_startup])
# Variable substitutions # Variable substitutions
AM_CONDITIONAL(WANT_GUI, test x$enable_gui = xyes) AM_CONDITIONAL(WANT_GUI, test x$enable_gui = xyes)
AM_CONDITIONAL(WANT_DAEMON, test x$enable_daemon = xyes) AM_CONDITIONAL(WANT_DAEMON, test x$enable_daemon = xyes)
AM_CONDITIONAL(WANT_BSD, test x$want_bsd = xyes)
AM_CONDITIONAL(WANT_DOCS, test x$want_docs = xyes) AM_CONDITIONAL(WANT_DOCS, test x$want_docs = xyes)
AM_CONDITIONAL(WANT_PYTHON, test x$want_python = xyes) AM_CONDITIONAL(WANT_PYTHON, test x$want_python = xyes)
AM_CONDITIONAL(WANT_NETNS, test x$want_linux_netns = xyes) AM_CONDITIONAL(WANT_NETNS, test x$want_linux_netns = xyes)
@ -370,19 +348,15 @@ ${PACKAGE_STRING} Configuration:
Features to build: Features to build:
Python bindings: ${want_python} Python bindings: ${want_python}
Linux Namespaces emulation: ${want_linux_netns} Linux Namespaces emulation: ${want_linux_netns}
FreeBSD Jails emulation: ${want_bsd}
Documentation: ${want_docs} Documentation: ${want_docs}
------------------------------------------------------------------------" ------------------------------------------------------------------------"
if test "x${want_bsd}" = "xyes" ; then
# TODO: more sophisticated checks of gmake vs make
echo ">>> NOTE: on FreeBSD you should use 'gmake' instead of 'make'
------------------------------------------------------------------------"
fi
if test "x${want_linux_netns}" = "xyes" ; then if test "x${want_linux_netns}" = "xyes" ; then
echo "On this platform you should run core-gui as a normal user. echo "On this platform you should run core-gui as a normal user.
------------------------------------------------------------------------" ------------------------------------------------------------------------"
fi fi
if test "x${progs_missing}" != "x" ; then if test "x${progs_missing}" != "x" ; then
echo ">>> NOTE: the following programs could not be found:" echo ">>> NOTE: the following programs could not be found:"
echo " $progs_missing echo " $progs_missing

View file

@ -1,89 +0,0 @@
"""
netgraph.py: Netgraph helper functions; for now these are wrappers around
ngctl commands.
"""
import subprocess
from core import constants
from core.misc import utils
utils.check_executables([constants.NGCTL_BIN])
def createngnode(node_type, hookstr, name=None):
"""
Create a new Netgraph node of type and optionally assign name. The
hook string hookstr should contain two names. This is a string so
other commands may be inserted after the two names.
Return the name and netgraph ID of the new node.
:param node_type: node type to create
:param hookstr: hook string
:param name: name
:return: name and id
:rtype: tuple
"""
hook1 = hookstr.split()[0]
ngcmd = "mkpeer %s %s \n show .%s" % (node_type, hookstr, hook1)
cmd = [constants.NGCTL_BIN, "-f", "-"]
cmdid = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
# err will always be None
result, err = cmdid.communicate(input=ngcmd)
status = cmdid.wait()
if status > 0:
raise Exception("error creating Netgraph node %s (%s): %s" % (node_type, ngcmd, result))
results = result.split()
ngname = results[1]
ngid = results[5]
if name:
subprocess.check_call([constants.NGCTL_BIN, "name", "[0x%s]:" % ngid, name])
return ngname, ngid
def destroyngnode(name):
"""
Shutdown a Netgraph node having the given name.
:param str name: node name
:return: nothing
"""
subprocess.check_call([constants.NGCTL_BIN, "shutdown", "%s:" % name])
def connectngnodes(name1, name2, hook1, hook2):
"""
Connect two hooks of two Netgraph nodes given by their names.
:param str name1: name one
:param str name2: name two
:param str hook1: hook one
:param str hook2: hook two
:return: nothing
"""
node1 = "%s:" % name1
node2 = "%s:" % name2
subprocess.check_call([constants.NGCTL_BIN, "connect", node1, node2, hook1, hook2])
def ngmessage(name, msg):
"""
Send a Netgraph message to the node named name.
:param str name: node name
:param list msg: message
:return: nothing
"""
cmd = [constants.NGCTL_BIN, "msg", "%s:" % name] + msg
subprocess.check_call(cmd)
def ngloadkernelmodule(name):
"""
Load a kernel module by invoking kldstat. This is needed for the
ng_ether module which automatically creates Netgraph nodes when loaded.
:param str name: module name
:return: nothing
"""
utils.check_cmd(["kldload", name])

View file

@ -1,212 +0,0 @@
"""
nodes.py: definition of CoreNode classes and other node classes that inherit
from the CoreNode, implementing specific node types.
"""
import socket
import subprocess
from core import constants
from core import logger
from core.api import coreapi
from core.bsd.netgraph import connectngnodes
from core.bsd.netgraph import ngloadkernelmodule
from core.bsd.vnet import NetgraphNet
from core.bsd.vnet import NetgraphPipeNet
from core.bsd.vnode import JailNode
from core.enumerations import LinkTlvs
from core.enumerations import LinkTypes
from core.enumerations import NodeTypes
from core.enumerations import RegisterTlvs
from core.misc import ipaddress
from core.misc import utils
utils.check_executables([constants.IFCONFIG_BIN])
class CoreNode(JailNode):
apitype = NodeTypes.DEFAULT.value
class PtpNet(NetgraphPipeNet):
def tonodemsg(self, flags):
"""
Do not generate a Node Message for point-to-point links. They are
built using a link message instead.
"""
pass
def tolinkmsgs(self, flags):
"""
Build CORE API TLVs for a point-to-point link. One Link message
describes this network.
"""
tlvdata = ""
if len(self._netif) != 2:
return tlvdata
(if1, if2) = self._netif.items()
if1 = if1[1]
if2 = if2[1]
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.N1_NUMBER.value, if1.node.objid)
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.N2_NUMBER.value, if2.node.objid)
delay = if1.getparam("delay")
bw = if1.getparam("bw")
loss = if1.getparam("loss")
duplicate = if1.getparam("duplicate")
jitter = if1.getparam("jitter")
if delay is not None:
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.DELAY.value, delay)
if bw is not None:
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.BANDWIDTH.value, bw)
if loss is not None:
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.PER.value, str(loss))
if duplicate is not None:
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.DUP.value, str(duplicate))
if jitter is not None:
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.JITTER.value, jitter)
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.TYPE.value, self.linktype)
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE1_NUMBER.value, if1.node.getifindex(if1))
if if1.hwaddr:
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE1_MAC.value, if1.hwaddr)
for addr in if1.addrlist:
ip, sep, mask = addr.partition("/")
mask = int(mask)
if ipaddress.is_ipv4_address(ip):
family = socket.AF_INET
tlvtypeip = LinkTlvs.INTERFACE1_IP4.value
tlvtypemask = LinkTlvs.INTERFACE1_IP4_MASK
else:
family = socket.AF_INET6
tlvtypeip = LinkTlvs.INTERFACE1_IP6.value
tlvtypemask = LinkTlvs.INTERFACE1_IP6_MASK.value
ipl = socket.inet_pton(family, ip)
tlvdata += coreapi.CoreLinkTlv.pack(tlvtypeip, ipaddress.IpAddress(af=family, address=ipl))
tlvdata += coreapi.CoreLinkTlv.pack(tlvtypemask, mask)
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_NUMBER.value, if2.node.getifindex(if2))
if if2.hwaddr:
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.INTERFACE2_MAC.value, if2.hwaddr)
for addr in if2.addrlist:
ip, sep, mask = addr.partition("/")
mask = int(mask)
if ipaddress.is_ipv4_address(ip):
family = socket.AF_INET
tlvtypeip = LinkTlvs.INTERFACE2_IP4.value
tlvtypemask = LinkTlvs.INTERFACE2_IP4_MASK
else:
family = socket.AF_INET6
tlvtypeip = LinkTlvs.INTERFACE2_IP6.value
tlvtypemask = LinkTlvs.INTERFACE2_IP6_MASK.value
ipl = socket.inet_pton(family, ip)
tlvdata += coreapi.CoreLinkTlv.pack(tlvtypeip, ipaddress.IpAddress(af=family, address=ipl))
tlvdata += coreapi.CoreLinkTlv.pack(tlvtypemask, mask)
msg = coreapi.CoreLinkMessage.pack(flags, tlvdata)
return [msg, ]
class SwitchNode(NetgraphNet):
ngtype = "bridge"
nghooks = "link0 link0\nmsg .link0 setpersistent"
apitype = NodeTypes.SWITCH.value
policy = "ACCEPT"
class HubNode(NetgraphNet):
ngtype = "hub"
nghooks = "link0 link0\nmsg .link0 setpersistent"
apitype = NodeTypes.HUB.value
policy = "ACCEPT"
class WlanNode(NetgraphNet):
ngtype = "wlan"
nghooks = "anchor anchor"
apitype = NodeTypes.WIRELESS_LAN.value
linktype = LinkTypes.WIRELESS.value
policy = "DROP"
def __init__(self, session, objid=None, name=None, start=True, policy=None):
NetgraphNet.__init__(self, session, objid, name, start, policy)
# wireless model such as basic range
self.model = None
# mobility model such as scripted
self.mobility = None
def attach(self, netif):
NetgraphNet.attach(self, netif)
if self.model:
netif.poshook = self.model.position_callback
if netif.node is None:
return
x, y, z = netif.node.position.get()
netif.poshook(netif, x, y, z)
def setmodel(self, model, config):
"""
Mobility and wireless model.
:param core.mobility.WirelessModel.cls model: model to set
:param dict config: configuration for model
:return:
"""
logger.info("adding model %s" % model.name)
if model.config_type == RegisterTlvs.WIRELESS.value:
self.model = model(session=self.session, objid=self.objid, values=config)
if self.model.position_callback:
for netif in self.netifs():
netif.poshook = self.model.position_callback
if netif.node is not None:
x, y, z = netif.node.position.get()
netif.poshook(netif, x, y, z)
self.model.setlinkparams()
elif model.config_type == RegisterTlvs.MOBILITY.value:
self.mobility = model(session=self.session, objid=self.objid, values=config)
class RJ45Node(NetgraphPipeNet):
apitype = NodeTypes.RJ45.value
policy = "ACCEPT"
def __init__(self, session, objid, name, start=True):
if start:
ngloadkernelmodule("ng_ether")
NetgraphPipeNet.__init__(self, session, objid, name, start)
if start:
self.setpromisc(True)
def shutdown(self):
self.setpromisc(False)
NetgraphPipeNet.shutdown(self)
def setpromisc(self, promisc):
p = "promisc"
if not promisc:
p = "-" + p
subprocess.check_call([constants.IFCONFIG_BIN, self.name, "up", p])
def attach(self, netif):
if len(self._netif) > 0:
raise ValueError("RJ45 networks support at most 1 network interface")
NetgraphPipeNet.attach(self, netif)
connectngnodes(self.ngname, self.name, self.gethook(), "lower")
class TunnelNode(NetgraphNet):
ngtype = "pipe"
nghooks = "upper lower"
apitype = NodeTypes.TUNNEL.value
policy = "ACCEPT"
BSD_NODES = {
NodeTypes.DEFAULT: CoreNode,
NodeTypes.SWITCH: SwitchNode,
NodeTypes.HUB: HubNode,
NodeTypes.WIRELESS_LAN: WlanNode,
NodeTypes.RJ45: RJ45Node,
NodeTypes.TUNNEL: TunnelNode,
NodeTypes.PEER_TO_PEER: PtpNet,
NodeTypes.CONTROL_NET: None
}

View file

@ -1,206 +0,0 @@
"""
vnet.py: NetgraphNet and NetgraphPipeNet classes that implement virtual networks
using the FreeBSD Netgraph subsystem.
"""
from core import logger
from core.bsd.netgraph import connectngnodes
from core.bsd.netgraph import createngnode
from core.bsd.netgraph import destroyngnode
from core.bsd.netgraph import ngmessage
from core.coreobj import PyCoreNet
class NetgraphNet(PyCoreNet):
ngtype = None
nghooks = ()
def __init__(self, session, objid=None, name=None, start=True, policy=None):
PyCoreNet.__init__(self, session, objid, name)
if name is None:
name = str(self.objid)
if policy is not None:
self.policy = policy
self.name = name
self.ngname = "n_%s_%s" % (str(self.objid), self.session.session_id)
self.ngid = None
self._netif = {}
self._linked = {}
self.up = False
if start:
self.startup()
def startup(self):
tmp, self.ngid = createngnode(node_type=self.ngtype, hookstr=self.nghooks, name=self.ngname)
self.up = True
def shutdown(self):
if not self.up:
return
self.up = False
while self._netif:
k, netif = self._netif.popitem()
if netif.pipe:
pipe = netif.pipe
netif.pipe = None
pipe.shutdown()
else:
netif.shutdown()
self._netif.clear()
self._linked.clear()
del self.session
destroyngnode(self.ngname)
def attach(self, netif):
"""
Attach an interface to this netgraph node. Create a pipe between
the interface and the hub/switch/wlan node.
(Note that the PtpNet subclass overrides this method.)
"""
if self.up:
pipe = self.session.addobj(cls=NetgraphPipeNet, start=True)
pipe.attach(netif)
hook = "link%d" % len(self._netif)
pipe.attachnet(self, hook)
PyCoreNet.attach(self, netif)
def detach(self, netif):
PyCoreNet.detach(self, netif)
def linked(self, netif1, netif2):
# check if the network interfaces are attached to this network
if self._netif[netif1] != netif1:
raise ValueError("inconsistency for netif %s" % netif1.name)
if self._netif[netif2] != netif2:
raise ValueError("inconsistency for netif %s" % netif2.name)
try:
linked = self._linked[netif1][netif2]
except KeyError:
linked = False
self._linked[netif1][netif2] = linked
return linked
def unlink(self, netif1, netif2):
if not self.linked(netif1, netif2):
return
msg = ["unlink", "{", "node1=0x%s" % netif1.pipe.ngid]
msg += ["node2=0x%s" % netif2.pipe.ngid, "}"]
ngmessage(self.ngname, msg)
self._linked[netif1][netif2] = False
def link(self, netif1, netif2):
if self.linked(netif1, netif2):
return
msg = ["link", "{", "node1=0x%s" % netif1.pipe.ngid]
msg += ["node2=0x%s" % netif2.pipe.ngid, "}"]
ngmessage(self.ngname, msg)
self._linked[netif1][netif2] = True
def linknet(self, net):
"""
Link this bridge with another by creating a veth pair and installing
each device into each bridge.
"""
raise NotImplementedError
def linkconfig(self, netif, bw=None, delay=None,
loss=None, duplicate=None, jitter=None, netif2=None):
"""
Set link effects by modifying the pipe connected to an interface.
"""
if not netif.pipe:
logger.warn("linkconfig for %s but interface %s has no pipe", self.name, netif.name)
return
return netif.pipe.linkconfig(netif, bw, delay, loss, duplicate, jitter, netif2)
class NetgraphPipeNet(NetgraphNet):
ngtype = "pipe"
nghooks = "upper lower"
def __init__(self, session, objid=None, name=None, start=True, policy=None):
NetgraphNet.__init__(self, session, objid, name, start, policy)
if start:
# account for Ethernet header
ngmessage(self.ngname, ["setcfg", "{", "header_offset=14", "}"])
def attach(self, netif):
"""
Attach an interface to this pipe node.
The first interface is connected to the "upper" hook, the second
connected to the "lower" hook.
"""
if len(self._netif) > 1:
raise ValueError("Netgraph pipes support at most 2 network interfaces")
if self.up:
hook = self.gethook()
connectngnodes(self.ngname, netif.localname, hook, netif.hook)
if netif.pipe:
raise ValueError("Interface %s already attached to pipe %s" % (netif.name, netif.pipe.name))
netif.pipe = self
self._netif[netif] = netif
self._linked[netif] = {}
def attachnet(self, net, hook):
"""
Attach another NetgraphNet to this pipe node.
"""
localhook = self.gethook()
connectngnodes(self.ngname, net.ngname, localhook, hook)
def gethook(self):
"""
Returns the first hook (e.g. "upper") then the second hook
(e.g. "lower") based on the number of connections.
"""
hooks = self.nghooks.split()
if len(self._netif) == 0:
return hooks[0]
else:
return hooks[1]
def linkconfig(self, netif, bw=None, delay=None,
loss=None, duplicate=None, jitter=None, netif2=None):
"""
Set link effects by sending a Netgraph setcfg message to the pipe.
"""
netif.setparam("bw", bw)
netif.setparam("delay", delay)
netif.setparam("loss", loss)
netif.setparam("duplicate", duplicate)
netif.setparam("jitter", jitter)
if not self.up:
return
params = []
upstream = []
downstream = []
if bw is not None:
if str(bw) == "0":
bw = "-1"
params += ["bandwidth=%s" % bw, ]
if delay is not None:
if str(delay) == "0":
delay = "-1"
params += ["delay=%s" % delay, ]
if loss is not None:
if str(loss) == "0":
loss = "-1"
upstream += ["BER=%s" % loss, ]
downstream += ["BER=%s" % loss, ]
if duplicate is not None:
if str(duplicate) == "0":
duplicate = "-1"
upstream += ["duplicate=%s" % duplicate, ]
downstream += ["duplicate=%s" % duplicate, ]
if jitter:
logger.warn("jitter parameter ignored for link %s", self.name)
if len(params) > 0 or len(upstream) > 0 or len(downstream) > 0:
setcfg = ["setcfg", "{", ] + params
if len(upstream) > 0:
setcfg += ["upstream={", ] + upstream + ["}", ]
if len(downstream) > 0:
setcfg += ["downstream={", ] + downstream + ["}", ]
setcfg += ["}", ]
ngmessage(self.ngname, setcfg)

View file

@ -1,386 +0,0 @@
"""
vnode.py: SimpleJailNode and JailNode classes that implement the FreeBSD
jail-based virtual node.
"""
import os
import subprocess
import threading
from core import constants
from core import logger
from core.bsd.netgraph import createngnode
from core.bsd.netgraph import destroyngnode
from core.coreobj import PyCoreNetIf
from core.coreobj import PyCoreNode
from core.misc import utils
utils.check_executables([constants.IFCONFIG_BIN, constants.VIMAGE_BIN])
class VEth(PyCoreNetIf):
def __init__(self, node, name, localname, mtu=1500, net=None,
start=True):
PyCoreNetIf.__init__(self, node=node, name=name, mtu=mtu)
# name is the device name (e.g. ngeth0, ngeth1, etc.) before it is
# installed in a node; the Netgraph name is renamed to localname
# e.g. before install: name = ngeth0 localname = n0_0_123
# after install: name = eth0 localname = n0_0_123
self.localname = localname
self.ngid = None
self.net = None
self.pipe = None
self.addrlist = []
self.hwaddr = None
self.up = False
self.hook = "ether"
if start:
self.startup()
def startup(self):
hookstr = "%s %s" % (self.hook, self.hook)
ngname, ngid = createngnode(node_type="eiface", hookstr=hookstr, name=self.localname)
self.name = ngname
self.ngid = ngid
subprocess.check_call([constants.IFCONFIG_BIN, ngname, "up"])
self.up = True
def shutdown(self):
if not self.up:
return
destroyngnode(self.localname)
self.up = False
def attachnet(self, net):
if self.net:
self.detachnet()
self.net = None
net.attach(self)
self.net = net
def detachnet(self):
if self.net is not None:
self.net.detach(self)
def addaddr(self, addr):
self.addrlist.append(addr)
def deladdr(self, addr):
self.addrlist.remove(addr)
def sethwaddr(self, addr):
self.hwaddr = addr
class TunTap(PyCoreNetIf):
"""
TUN/TAP virtual device in TAP mode
"""
def __init__(self, node, name, localname, mtu=None, net=None, start=True):
raise NotImplementedError
class SimpleJailNode(PyCoreNode):
def __init__(self, session, objid=None, name=None, nodedir=None):
PyCoreNode.__init__(self, session, objid, name)
self.nodedir = nodedir
self.pid = None
self.up = False
self.lock = threading.RLock()
self._mounts = []
def startup(self):
if self.up:
raise Exception("already up")
vimg = [constants.VIMAGE_BIN, "-c", self.name]
try:
os.spawnlp(os.P_WAIT, constants.VIMAGE_BIN, *vimg)
except OSError:
raise Exception("vimage command not found while running: %s" % vimg)
logger.info("bringing up loopback interface")
self.cmd([constants.IFCONFIG_BIN, "lo0", "127.0.0.1"])
logger.info("setting hostname: %s", self.name)
self.cmd(["hostname", self.name])
self.cmd([constants.SYSCTL_BIN, "vfs.morphing_symlinks=1"])
self.up = True
def shutdown(self):
if not self.up:
return
for netif in self.netifs():
netif.shutdown()
self._netif.clear()
del self.session
vimg = [constants.VIMAGE_BIN, "-d", self.name]
try:
os.spawnlp(os.P_WAIT, constants.VIMAGE_BIN, *vimg)
except OSError:
raise Exception("vimage command not found while running: %s" % vimg)
self.up = False
def cmd(self, args, wait=True):
if wait:
mode = os.P_WAIT
else:
mode = os.P_NOWAIT
tmp = subprocess.call([constants.VIMAGE_BIN, self.name] + args, cwd=self.nodedir)
if not wait:
tmp = None
if tmp:
logger.warn("cmd exited with status %s: %s", tmp, str(args))
return tmp
def cmdresult(self, args, wait=True):
cmdid, cmdin, cmdout, cmderr = self.popen(args)
result = cmdout.read()
result += cmderr.read()
cmdin.close()
cmdout.close()
cmderr.close()
if wait:
status = cmdid.wait()
else:
status = 0
return status, result
def popen(self, args):
cmd = [constants.VIMAGE_BIN, self.name]
cmd.extend(args)
tmp = subprocess.Popen(cmd, stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE, cwd=self.nodedir)
return tmp, tmp.stdin, tmp.stdout, tmp.stderr
def icmd(self, args):
return os.spawnlp(os.P_WAIT, constants.VIMAGE_BIN, constants.VIMAGE_BIN, self.name, *args)
def term(self, sh="/bin/sh"):
return os.spawnlp(os.P_WAIT, "xterm", "xterm", "-ut",
"-title", self.name, "-e", constants.VIMAGE_BIN, self.name, sh)
def termcmdstring(self, sh="/bin/sh"):
"""
We add "sudo" to the command string because the GUI runs as a
normal user.
"""
return "cd %s && sudo %s %s %s" % (self.nodedir, constants.VIMAGE_BIN, self.name, sh)
def shcmd(self, cmdstr, sh="/bin/sh"):
return self.cmd([sh, "-c", cmdstr])
def boot(self):
pass
def mount(self, source, target):
source = os.path.abspath(source)
logger.info("mounting %s at %s", source, target)
self.addsymlink(path=target, file=None)
def umount(self, target):
logger.info("unmounting %s", target)
def newveth(self, ifindex=None, ifname=None, net=None):
self.lock.acquire()
try:
if ifindex is None:
ifindex = self.newifindex()
if ifname is None:
ifname = "eth%d" % ifindex
sessionid = self.session.short_session_id()
name = "n%s_%s_%s" % (self.objid, ifindex, sessionid)
localname = name
ifclass = VEth
veth = ifclass(node=self, name=name, localname=localname,
mtu=1500, net=net, start=self.up)
if self.up:
# install into jail
subprocess.check_call([constants.IFCONFIG_BIN, veth.name, "vnet", self.name])
# rename from "ngeth0" to "eth0"
self.cmd([constants.IFCONFIG_BIN, veth.name, "name", ifname])
veth.name = ifname
try:
self.addnetif(veth, ifindex)
except:
veth.shutdown()
del veth
raise
return ifindex
finally:
self.lock.release()
def sethwaddr(self, ifindex, addr):
self._netif[ifindex].sethwaddr(addr)
if self.up:
self.cmd([constants.IFCONFIG_BIN, self.ifname(ifindex), "link", str(addr)])
def addaddr(self, ifindex, addr):
if self.up:
if ":" in addr:
family = "inet6"
else:
family = "inet"
self.cmd([constants.IFCONFIG_BIN, self.ifname(ifindex), family, "alias", str(addr)])
self._netif[ifindex].addaddr(addr)
def deladdr(self, ifindex, addr):
try:
self._netif[ifindex].deladdr(addr)
except ValueError:
logger.warn("trying to delete unknown address: %s", addr)
if self.up:
if ":" in addr:
family = "inet6"
else:
family = "inet"
self.cmd([constants.IFCONFIG_BIN, self.ifname(ifindex), family, "-alias",
str(addr)])
valid_deladdrtype = ("inet", "inet6", "inet6link")
def delalladdr(self, ifindex, addrtypes=valid_deladdrtype):
addr = self.getaddr(self.ifname(ifindex), rescan=True)
for t in addrtypes:
if t not in self.valid_deladdrtype:
raise ValueError("addr type must be in: " + " ".join(self.valid_deladdrtype))
for a in addr[t]:
self.deladdr(ifindex, a)
# update cached information
self.getaddr(self.ifname(ifindex), rescan=True)
def ifup(self, ifindex):
if self.up:
self.cmd([constants.IFCONFIG_BIN, self.ifname(ifindex), "up"])
def newnetif(self, net=None, addrlist=[], hwaddr=None,
ifindex=None, ifname=None):
self.lock.acquire()
try:
ifindex = self.newveth(ifindex=ifindex, ifname=ifname, net=net)
if net is not None:
self.attachnet(ifindex, net)
if hwaddr:
self.sethwaddr(ifindex, hwaddr)
for addr in utils.make_tuple(addrlist):
self.addaddr(ifindex, addr)
self.ifup(ifindex)
return ifindex
finally:
self.lock.release()
def attachnet(self, ifindex, net):
self._netif[ifindex].attachnet(net)
def detachnet(self, ifindex):
self._netif[ifindex].detachnet()
def addfile(self, srcname, filename):
shcmd = 'mkdir -p $(dirname "%s") && mv "%s" "%s" && sync' % (filename, srcname, filename)
self.shcmd(shcmd)
def getaddr(self, ifname, rescan=False):
return None
def addsymlink(self, path, file):
"""
Create a symbolic link from /path/name/file ->
/tmp/pycore.nnnnn/@.conf/path.name/file
"""
dirname = path
if dirname and dirname[0] == "/":
dirname = dirname[1:]
dirname = dirname.replace("/", ".")
if file:
pathname = os.path.join(path, file)
sym = os.path.join(self.session.session_dir, "@.conf", dirname, file)
else:
pathname = path
sym = os.path.join(self.session.session_dir, "@.conf", dirname)
if os.path.islink(pathname):
if os.readlink(pathname) == sym:
# this link already exists - silently return
return
os.unlink(pathname)
else:
if os.path.exists(pathname):
logger.warn("did not create symlink for %s since path exists on host", pathname)
return
logger.info("creating symlink %s -> %s", pathname, sym)
os.symlink(sym, pathname)
class JailNode(SimpleJailNode):
def __init__(self, session, objid=None, name=None, nodedir=None, bootsh="boot.sh", start=True):
super(JailNode, self).__init__(session=session, objid=objid, name=name, nodedir=nodedir)
self.bootsh = bootsh
if not start:
return
# below here is considered node startup/instantiation code
self.makenodedir()
self.startup()
def boot(self):
self.session.services.bootnodeservices(self)
def validate(self):
self.session.services.validatenodeservices(self)
def startup(self):
self.lock.acquire()
try:
super(JailNode, self).startup()
# self.privatedir("/var/run")
# self.privatedir("/var/log")
finally:
self.lock.release()
def shutdown(self):
if not self.up:
return
self.lock.acquire()
# services are instead stopped when session enters datacollect state
# self.session.services.stopnodeservices(self)
try:
super(JailNode, self).shutdown()
finally:
self.rmnodedir()
self.lock.release()
def privatedir(self, path):
if path[0] != "/":
raise ValueError, "path not fully qualified: " + path
hostpath = os.path.join(
self.nodedir,
os.path.normpath(path).strip("/").replace("/", ".")
)
try:
os.mkdir(hostpath)
except OSError:
pass
except Exception, e:
raise Exception, e
self.mount(hostpath, path)
def opennodefile(self, filename, mode="w"):
dirname, basename = os.path.split(filename)
# self.addsymlink(path=dirname, file=basename)
if not basename:
raise ValueError("no basename for filename: %s" % filename)
if dirname and dirname[0] == "/":
dirname = dirname[1:]
dirname = dirname.replace("/", ".")
dirname = os.path.join(self.nodedir, dirname)
if not os.path.isdir(dirname):
os.makedirs(dirname, mode=0755)
hostfilename = os.path.join(dirname, basename)
return open(hostfilename, mode)
def nodefile(self, filename, contents, mode=0644):
f = self.opennodefile(filename, "w")
f.write(contents)
os.chmod(f.name, mode)
f.close()
logger.info("created nodefile: %s; mode: 0%o", f.name, mode)

View file

@ -87,9 +87,7 @@ class CoreServices(ConfigurableManager):
name = "services" name = "services"
config_type = RegisterTlvs.UTILITY.value config_type = RegisterTlvs.UTILITY.value
_invalid_custom_names = ( _invalid_custom_names = ('core', 'api', 'emane', 'misc', 'netns', 'phys', 'services', 'xen')
'core', 'api', 'bsd', 'emane', 'misc', 'netns', 'phys', 'services', 'xen'
)
def __init__(self, session): def __init__(self, session):
""" """
@ -763,7 +761,7 @@ class CoreServices(ConfigurableManager):
cfg = self.getservicefiledata(s, filename) cfg = self.getservicefiledata(s, filename)
if cfg is None: if cfg is None:
cfg = s.generateconfig(node, filename, services) cfg = s.generateconfig(node, filename, services)
node.nodefile(filename, cfg) node.nodefile(filename, cfg)
fail_data = "" fail_data = ""

View file

@ -298,8 +298,7 @@ class OlsrOrg(NrlService):
####################################### #######################################
### Linux specific OLSRd extensions ### ### Linux specific OLSRd extensions ###
####################################### #######################################
# these parameters are only working on linux at the moment, but might become # these parameters are only working on linux at the moment
# useful on BSD in the future
# SrcIpRoutes tells OLSRd to set the Src flag of host routes to the originator-ip # SrcIpRoutes tells OLSRd to set the Src flag of host routes to the originator-ip
# of the node. In addition to this an additional localhost device is created # of the node. In addition to this an additional localhost device is created
@ -516,7 +515,7 @@ LinkQualityFishEye 0
# - /lib, followed by /usr/lib # - /lib, followed by /usr/lib
# #
# the examples in this list are for linux, so check if the plugin is # the examples in this list are for linux, so check if the plugin is
# available if you use windows/BSD. # available if you use windows.
# each plugin should have a README file in it's lib subfolder # each plugin should have a README file in it's lib subfolder
# LoadPlugin "olsrd_txtinfo.dll" # LoadPlugin "olsrd_txtinfo.dll"

View file

@ -40,10 +40,8 @@ class IPForwardService(UtilService):
def generateconfig(cls, node, filename, services): def generateconfig(cls, node, filename, services):
if os.uname()[0] == "Linux": if os.uname()[0] == "Linux":
return cls.generateconfiglinux(node, filename, services) return cls.generateconfiglinux(node, filename, services)
elif os.uname()[0] == "FreeBSD":
return cls.generateconfigbsd(node, filename, services)
else: else:
raise Exception, "unknown platform" raise Exception("unknown platform")
@classmethod @classmethod
def generateconfiglinux(cls, node, filename, services): def generateconfiglinux(cls, node, filename, services):
@ -67,17 +65,6 @@ class IPForwardService(UtilService):
cfg += "%s -w net.ipv4.conf.%s.rp_filter=0\n" % (constants.SYSCTL_BIN, name) cfg += "%s -w net.ipv4.conf.%s.rp_filter=0\n" % (constants.SYSCTL_BIN, name)
return cfg return cfg
@classmethod
def generateconfigbsd(cls, node, filename, services):
return """\
#!/bin/sh
# auto-generated by IPForward service (utility.py)
%s -w net.inet.ip.forwarding=1
%s -w net.inet6.ip6.forwarding=1
%s -w net.inet.icmp.bmcastecho=1
%s -w net.inet.icmp.icmplim=0
""" % (constants.SYSCTL_BIN, constants.SYSCTL_BIN, constants.SYSCTL_BIN, constants.SYSCTL_BIN)
class DefaultRouteService(UtilService): class DefaultRouteService(UtilService):
_name = "DefaultRoute" _name = "DefaultRoute"
@ -108,10 +95,8 @@ class DefaultRouteService(UtilService):
else: else:
if os.uname()[0] == "Linux": if os.uname()[0] == "Linux":
rtcmd = "ip route add default via" rtcmd = "ip route add default via"
elif os.uname()[0] == "FreeBSD":
rtcmd = "route add -%s" % fam
else: else:
raise Exception, "unknown platform" raise Exception("unknown platform")
return "%s %s" % (rtcmd, net.min_addr()) return "%s %s" % (rtcmd, net.min_addr())
@ -132,10 +117,8 @@ class DefaultMulticastRouteService(UtilService):
continue continue
if os.uname()[0] == "Linux": if os.uname()[0] == "Linux":
rtcmd = "ip route add 224.0.0.0/4 dev" rtcmd = "ip route add 224.0.0.0/4 dev"
elif os.uname()[0] == "FreeBSD":
rtcmd = "route add 224.0.0.0/4 -iface"
else: else:
raise Exception, "unknown platform" raise Exception("unknown platform")
cfg += "%s %s\n" % (rtcmd, ifc.name) cfg += "%s %s\n" % (rtcmd, ifc.name)
cfg += "\n" cfg += "\n"
break break
@ -176,21 +159,15 @@ class StaticRouteService(UtilService):
else: else:
if os.uname()[0] == "Linux": if os.uname()[0] == "Linux":
rtcmd = "#/sbin/ip route add %s via" % dst rtcmd = "#/sbin/ip route add %s via" % dst
elif os.uname()[0] == "FreeBSD":
rtcmd = "#/sbin/route add -%s %s" % (fam, dst)
else: else:
raise Exception, "unknown platform" raise Exception("unknown platform")
return "%s %s" % (rtcmd, net.min_addr()) return "%s %s" % (rtcmd, net.min_addr())
class SshService(UtilService): class SshService(UtilService):
_name = "SSH" _name = "SSH"
if os.uname()[0] == "FreeBSD": _configs = ("startsshd.sh", "/etc/ssh/sshd_config",)
_configs = ("startsshd.sh", "sshd_config",) _dirs = ("/etc/ssh", "/var/run/sshd",)
_dirs = ()
else:
_configs = ("startsshd.sh", "/etc/ssh/sshd_config",)
_dirs = ("/etc/ssh", "/var/run/sshd",)
_startup = ("sh startsshd.sh",) _startup = ("sh startsshd.sh",)
_shutdown = ("killall sshd",) _shutdown = ("killall sshd",)
_validate = () _validate = ()
@ -201,14 +178,9 @@ class SshService(UtilService):
Use a startup script for launching sshd in order to wait for host Use a startup script for launching sshd in order to wait for host
key generation. key generation.
""" """
if os.uname()[0] == "FreeBSD": sshcfgdir = cls._dirs[0]
sshcfgdir = node.nodedir sshstatedir = cls._dirs[1]
sshstatedir = node.nodedir sshlibdir = "/usr/lib/openssh"
sshlibdir = "/usr/libexec"
else:
sshcfgdir = cls._dirs[0]
sshstatedir = cls._dirs[1]
sshlibdir = "/usr/lib/openssh"
if filename == "startsshd.sh": if filename == "startsshd.sh":
return """\ return """\
#!/bin/sh #!/bin/sh

View file

@ -933,7 +933,7 @@ class Session(object):
""" """
with self._objects_lock: with self._objects_lock:
for obj in self.objects.itervalues(): for obj in self.objects.itervalues():
# TODO: PyCoreNode is not the type to check, but there are two types, due to bsd and netns # TODO: PyCoreNode is not the type to check
if isinstance(obj, nodes.PyCoreNode) and not nodeutils.is_node(obj, NodeTypes.RJ45): if isinstance(obj, nodes.PyCoreNode) and not nodeutils.is_node(obj, NodeTypes.RJ45):
# add a control interface if configured # add a control interface if configured
logger.info("booting node: %s - %s", obj.objid, obj.name) logger.info("booting node: %s - %s", obj.objid, obj.name)

View file

@ -319,12 +319,6 @@ if __name__ == "__main__":
nodeutils.update_node_map(OVS_NODES) nodeutils.update_node_map(OVS_NODES)
# update with BSD based nodes
if os.uname()[0] == "FreeBSD":
from core.bsd.nodes import BSD_NODES
nodeutils.update_node_map(BSD_NODES)
# load default services # load default services
services.load() services.load()

View file

@ -4,15 +4,13 @@
.. |CENTOSVERSION| replace:: 6.x or 7.x .. |CENTOSVERSION| replace:: 6.x or 7.x
.. |BSDVERSION| replace:: 9.0
.. |CORERPM| replace:: 1.fc20.x86_64.rpm .. |CORERPM| replace:: 1.fc20.x86_64.rpm
.. |CORERPM2| replace:: 1.fc20.noarch.rpm .. |CORERPM2| replace:: 1.fc20.noarch.rpm
.. |COREDEB| replace:: 0ubuntu1_precise_amd64.deb .. |COREDEB| replace:: 0ubuntu1_precise_amd64.deb
.. |COREDEB2| replace:: 0ubuntu1_precise_all.deb .. |COREDEB2| replace:: 0ubuntu1_precise_all.deb
.. |QVER| replace:: quagga-0.99.21mr2.2 .. |QVER| replace:: quagga-0.99.21mr2.2
.. |QVERDEB| replace:: quagga-mr_0.99.21mr2.2_amd64.deb .. |QVERDEB| replace:: quagga-mr_0.99.21mr2.2_amd64.deb
.. |QVERRPM| replace:: quagga-0.99.21mr2.2-1.fc16.x86_64.rpm .. |QVERRPM| replace:: quagga-0.99.21mr2.2-1.fc16.x86_64.rpm
.. |APTDEPS| replace:: bash bridge-utils ebtables iproute libev-dev python .. |APTDEPS| replace:: bash bridge-utils ebtables iproute libev-dev python
@ -20,6 +18,6 @@
.. |APTDEPS3| replace:: autoconf automake gcc libev-dev make python-dev libreadline-dev pkg-config imagemagick help2man .. |APTDEPS3| replace:: autoconf automake gcc libev-dev make python-dev libreadline-dev pkg-config imagemagick help2man
.. |YUMDEPS| replace:: bash bridge-utils ebtables iproute libev python procps-ng net-tools .. |YUMDEPS| replace:: bash bridge-utils ebtables iproute libev python procps-ng net-tools
.. |YUMDEPS2| replace:: tcl tk tkimg .. |YUMDEPS2| replace:: tcl tk tkimg
.. |YUMDEPS3| replace:: autoconf automake make libev-devel python-devel ImageMagick help2man .. |YUMDEPS3| replace:: autoconf automake make libev-devel python-devel ImageMagick help2man

View file

@ -39,10 +39,6 @@ These are being actively developed as of CORE |version|:
* *doc* - Documentation for the manual lives here in reStructuredText format. * *doc* - Documentation for the manual lives here in reStructuredText format.
* *packaging* - Control files and script for building CORE packages are here. * *packaging* - Control files and script for building CORE packages are here.
These directories are not so actively developed:
* *kernel* - patches and modules mostly related to FreeBSD.
.. _The_CORE_API: .. _The_CORE_API:
The CORE API The CORE API
@ -59,8 +55,7 @@ The GUI communicates with the CORE daemon using the API. One emulation server
communicates with another using the API. The API also allows other systems to communicates with another using the API. The API also allows other systems to
interact with the CORE emulation. The API allows another system to add, remove, interact with the CORE emulation. The API allows another system to add, remove,
or modify nodes and links, and enables executing commands on the emulated or modify nodes and links, and enables executing commands on the emulated
systems. On FreeBSD, the API is used for enhancing the wireless LAN systems. Wireless link parameters are updated on-the-fly based on node
calculations. Wireless link parameters are updated on-the-fly based on node
positions. positions.
CORE listens on a local TCP port for API messages. The other system could be CORE listens on a local TCP port for API messages. The other system could be
@ -88,7 +83,7 @@ The *vnoded* daemon is the program used to create a new namespace, and
listen on a control channel for commands that may instantiate other processes. listen on a control channel for commands that may instantiate other processes.
This daemon runs as PID 1 in the container. It is launched automatically by This daemon runs as PID 1 in the container. It is launched automatically by
the CORE daemon. The control channel is a UNIX domain socket usually named the CORE daemon. The control channel is a UNIX domain socket usually named
:file:`/tmp/pycore.23098/n3`, for node 3 running on CORE :file:`/tmp/pycore.23098/n3`, for node 3 running on CORE
session 23098, for example. Root privileges are required for creating a new session 23098, for example. Root privileges are required for creating a new
namespace. namespace.
@ -107,13 +102,13 @@ using a command such as:
:: ::
gnome-terminal -e vcmd -c /tmp/pycore.50160/n1 -- bash gnome-terminal -e vcmd -c /tmp/pycore.50160/n1 -- bash
Similarly, the IPv4 routes Observer Widget will run a command to display the routing table using a command such as: Similarly, the IPv4 routes Observer Widget will run a command to display the routing table using a command such as:
:: ::
vcmd -c /tmp/pycore.50160/n1 -- /sbin/ip -4 ro vcmd -c /tmp/pycore.50160/n1 -- /sbin/ip -4 ro
.. index:: core-cleanup .. index:: core-cleanup
@ -139,7 +134,7 @@ network namespace emulation.
tc qdisc show tc qdisc show
# view the rules that make the wireless LAN work # view the rules that make the wireless LAN work
ebtables -L ebtables -L
Below is a transcript of creating two emulated nodes and connecting them together with a wired link: Below is a transcript of creating two emulated nodes and connecting them together with a wired link:
@ -179,156 +174,8 @@ Below is a transcript of creating two emulated nodes and connecting them togethe
# display connectivity and ping from node 1 to node 2 # display connectivity and ping from node 1 to node 2
brctl show brctl show
vcmd -c /tmp/n1.ctl -- ping 10.0.0.2 vcmd -c /tmp/n1.ctl -- ping 10.0.0.2
The above example script can be found as :file:`twonodes.sh` in the The above example script can be found as :file:`twonodes.sh` in the
:file:`examples/netns` directory. Use *core-cleanup* to clean up after the :file:`examples/netns` directory. Use *core-cleanup* to clean up after the
script. script.
.. _FreeBSD_Commands:
FreeBSD Commands
================
.. index:: vimage
.. index:: ngctl
.. index:: Netgraph
.. _FreeBSD_Kernel_Commands:
FreeBSD Kernel Commands
-----------------------
The FreeBSD kernel emulation controlled by CORE is realized through several
userspace commands. The CORE GUI itself could be thought of as a glorified
script that dispatches these commands to build and manage the kernel emulation.
* **vimage** - the vimage command, short for "virtual image", is used to
create lightweight virtual machines and execute commands within the virtual
image context. On a FreeBSD CORE machine, see the *vimage(8)* man page for
complete details. The vimage command comes from the VirtNet project which
virtualizes the FreeBSD network stack.
* **ngctl** - the ngctl command, short for "netgraph control", creates
Netgraph nodes and hooks, connects them together, and allows for various
interactions with the Netgraph nodes. See the *ngctl(8)* man page for
complete details. The ngctl command is built-in to FreeBSD because the
Netgraph system is part of the kernel.
Both commands must be run as root.
Some example usage of the *vimage* command follows below.
::
vimage # displays the current virtual image
vimage -l # lists running virtual images
vimage e0_n0 ps aux # list the processes running on node 0
for i in 1 2 3 4 5
do # execute a command on all nodes
vimage e0_n$i sysctl -w net.inet.ip.redirect=0
done
The *ngctl* command is more complex, due to the variety of Netgraph nodes
available and each of their options.
::
ngctl l # list active Netgraph nodes
ngctl show e0_n8: # display node hook information
ngctl msg e0_n0-n1: getstats # get pkt count statistics from a pipe node
ngctl shutdown \\[0x0da3\\]: # shut down unnamed node using hex node ID
There are many other combinations of commands not shown here. See the online
manual (man) pages for complete details.
Below is a transcript of creating two emulated nodes, `router0` and `router1`,
and connecting them together with a link:
.. index:: create nodes from command-line
.. index:: command-line
::
# create node 0
vimage -c e0_n0
vimage e0_n0 hostname router0
ngctl mkpeer eiface ether ether
vimage -i e0_n0 ngeth0 eth0
vimage e0_n0 ifconfig eth0 link 40:00:aa:aa:00:00
vimage e0_n0 ifconfig lo0 inet localhost
vimage e0_n0 sysctl net.inet.ip.forwarding=1
vimage e0_n0 sysctl net.inet6.ip6.forwarding=1
vimage e0_n0 ifconfig eth0 mtu 1500
# create node 1
vimage -c e0_n1
vimage e0_n1 hostname router1
ngctl mkpeer eiface ether ether
vimage -i e0_n1 ngeth1 eth0
vimage e0_n1 ifconfig eth0 link 40:00:aa:aa:0:1
vimage e0_n1 ifconfig lo0 inet localhost
vimage e0_n1 sysctl net.inet.ip.forwarding=1
vimage e0_n1 sysctl net.inet6.ip6.forwarding=1
vimage e0_n1 ifconfig eth0 mtu 1500
# create a link between n0 and n1
ngctl mkpeer eth0@e0_n0: pipe ether upper
ngctl name eth0@e0_n0:ether e0_n0-n1
ngctl connect e0_n0-n1: eth0@e0_n1: lower ether
ngctl msg e0_n0-n1: setcfg \\
{{ bandwidth=100000000 delay=0 upstream={ BER=0 dupl
icate=0 } downstream={ BER=0 duplicate=0 } }}
ngctl msg e0_n0-n1: setcfg {{ downstream={ fifo=1 } }}
ngctl msg e0_n0-n1: setcfg {{ downstream={ droptail=1 } }}
ngctl msg e0_n0-n1: setcfg {{ downstream={ queuelen=50 } }}
ngctl msg e0_n0-n1: setcfg {{ upstream={ fifo=1 } }}
ngctl msg e0_n0-n1: setcfg {{ upstream={ droptail=1 } }}
ngctl msg e0_n0-n1: setcfg {{ upstream={ queuelen=50 } }}
Other FreeBSD commands that may be of interest:
.. index:: FreeBSD commands
* **kldstat**, **kldload**, **kldunload** - list, load, and unload
FreeBSD kernel modules
* **sysctl** - display and modify various pieces of kernel state
* **pkg_info**, **pkg_add**, **pkg_delete** - list, add, or remove
FreeBSD software packages.
* **vtysh** - start a Quagga CLI for router configuration
Netgraph Nodes
--------------
.. index:: Netgraph
.. index:: Netgraph nodes
Each Netgraph node implements a protocol or processes data in some well-defined
manner (see the `netgraph(4)` man page). The netgraph source code is located
in `/usr/src/sys/netgraph`. There you might discover additional nodes that
implement some desired functionality, that have not yet been included in CORE.
Using certain kernel commands, you can likely include these types of nodes into
your CORE emulation.
The following Netgraph nodes are used by CORE:
* **ng_bridge** - switch node performs Ethernet bridging
* **ng_cisco** - Cisco HDLC serial links
* **ng_eiface** - virtual Ethernet interface that is assigned to each virtual machine
* **ng_ether** - physical Ethernet devices, used by the RJ45 tool
* **ng_hub** - hub node
* **ng_pipe** - used for wired Ethernet links, imposes packet delay, bandwidth restrictions, and other link characteristics
* **ng_socket** - socket used by *ngctl* utility
* **ng_wlan** - wireless LAN node

View file

@ -9,14 +9,14 @@
Installation Installation
************ ************
This chapter describes how to set up a CORE machine. Note that the easiest This chapter describes how to set up a CORE machine. Note that the easiest
way to install CORE is using a binary way to install CORE is using a binary
package on Ubuntu or Fedora (deb or rpm) using the distribution's package package on Ubuntu or Fedora (deb or rpm) using the distribution's package
manager manager
to automatically install dependencies, see :ref:`Installing_from_Packages`. to automatically install dependencies, see :ref:`Installing_from_Packages`.
Ubuntu and Fedora Linux are the recommended distributions for running CORE. Ubuntu |UBUNTUVERSION| and Fedora |FEDORAVERSION| ship with kernels with support for namespaces built-in. They support the latest hardware. However, Ubuntu and Fedora Linux are the recommended distributions for running CORE. Ubuntu |UBUNTUVERSION| and Fedora |FEDORAVERSION| ship with kernels with support for namespaces built-in. They support the latest hardware. However,
these distributions are not strictly required. CORE will likely work on other these distributions are not strictly required. CORE will likely work on other
flavors of Linux, see :ref:`Installing_from_Source`. flavors of Linux, see :ref:`Installing_from_Source`.
The primary dependencies are Tcl/Tk (8.5 or newer) for the GUI, and Python 2.6 or 2.7 for the CORE daemon. The primary dependencies are Tcl/Tk (8.5 or newer) for the GUI, and Python 2.6 or 2.7 for the CORE daemon.
@ -50,7 +50,7 @@ Prerequisites
.. index:: Prerequisites .. index:: Prerequisites
The Linux or FreeBSD operating system is required. The GUI uses the Tcl/Tk scripting toolkit, and the CORE daemon require Python. Details of the individual software packages required can be found in the installation steps. A Linux operating system is required. The GUI uses the Tcl/Tk scripting toolkit, and the CORE daemon requires Python. Details of the individual software packages required can be found in the installation steps.
.. _Required_Hardware: .. _Required_Hardware:
@ -61,7 +61,7 @@ Required Hardware
.. index:: System requirements .. index:: System requirements
Any computer capable of running Linux or FreeBSD should be able to run CORE. Since the physical machine will be hosting numerous virtual machines, as a general rule you should select a machine having as much RAM and CPU resources as possible. Any computer capable of running Linux should be able to run CORE. Since the physical machine will be hosting numerous virtual machines, as a general rule you should select a machine having as much RAM and CPU resources as possible.
A *general recommendation* would be: A *general recommendation* would be:
@ -70,9 +70,9 @@ A *general recommendation* would be:
* about 3 MB of free disk space (plus more for dependency packages such as Tcl/Tk) * about 3 MB of free disk space (plus more for dependency packages such as Tcl/Tk)
* X11 for the GUI, or remote X11 over SSH * X11 for the GUI, or remote X11 over SSH
The computer can be a laptop, desktop, or rack-mount server. A keyboard, mouse, The computer can be a laptop, desktop, or rack-mount server. A keyboard, mouse,
and monitor are not required if a network connection is available and monitor are not required if a network connection is available
for remotely accessing the machine. A 3D accelerated graphics card for remotely accessing the machine. A 3D accelerated graphics card
is not required. is not required.
.. _Required_Software: .. _Required_Software:
@ -80,18 +80,13 @@ is not required.
Required Software Required Software
----------------- -----------------
CORE requires the Linux or FreeBSD operating systems because it uses virtualization provided by the kernel. It does not run on the Windows or Mac OS X operating systems (unless it is running within a virtual machine guest.) There are two CORE requires a Linux operating systems because it uses virtualization provided by the kernel. It does not run on the Windows or Mac OS X operating systems (unless it is running within a virtual machine guest.)
different virtualization technologies that CORE can currently use: The virtualization technology that CORE currently uses:
Linux network namespaces and FreeBSD jails, Linux network namespaces,
see :ref:`How_Does_it_Work?` for virtualization details. see :ref:`How_Does_it_Work?` for virtualization details.
**Linux network namespaces is the recommended platform.** Development is focused here and it supports the latest features. It is the easiest to install because there is no need to patch, install, and run a special Linux kernel. **Linux network namespaces is the recommended platform.** Development is focused here and it supports the latest features. It is the easiest to install because there is no need to patch, install, and run a special Linux kernel.
FreeBSD |BSDVERSION|-RELEASE may offer the best scalability. If your
applications run under FreeBSD and you are comfortable with that platform,
this may be a good choice. Device and application support by BSD
may not be as extensive as Linux.
The CORE GUI requires the X.Org X Window system (X11), or can run over a The CORE GUI requires the X.Org X Window system (X11), or can run over a
remote X11 session. For specific Tcl/Tk, Python, and other libraries required remote X11 session. For specific Tcl/Tk, Python, and other libraries required
to run CORE, refer to the :ref:`Installation` section. to run CORE, refer to the :ref:`Installation` section.
@ -113,7 +108,7 @@ Installing from Packages
The easiest way to install CORE is using the pre-built packages. The package The easiest way to install CORE is using the pre-built packages. The package
managers on Ubuntu or Fedora will managers on Ubuntu or Fedora will
automatically install dependencies for you. automatically install dependencies for you.
You can obtain the CORE packages from the `CORE downloads <http://downloads.pf.itd.nrl.navy.mil/core/packages/>`_ page You can obtain the CORE packages from the `CORE downloads <http://downloads.pf.itd.nrl.navy.mil/core/packages/>`_ page
or `CORE GitHub <https://github.com/coreemu/core/releases>`_. or `CORE GitHub <https://github.com/coreemu/core/releases>`_.
@ -143,7 +138,7 @@ First install the Ubuntu |UBUNTUVERSION| operating system.
to select which Quagga package to use. to select which Quagga package to use.
* **Optional:** install the prerequisite packages (otherwise skip this * **Optional:** install the prerequisite packages (otherwise skip this
step and have the package manager install them for you.) step and have the package manager install them for you.)
.. parsed-literal:: .. parsed-literal::
@ -152,13 +147,13 @@ First install the Ubuntu |UBUNTUVERSION| operating system.
# update-manager instead of apt-get update/dist-upgrade # update-manager instead of apt-get update/dist-upgrade
sudo apt-get update sudo apt-get update
sudo apt-get dist-upgrade sudo apt-get dist-upgrade
sudo apt-get install |APTDEPS| |APTDEPS2| sudo apt-get install |APTDEPS| |APTDEPS2|
* Install Quagga for routing. If you plan on working with wireless * Install Quagga for routing. If you plan on working with wireless
networks, we recommend networks, we recommend
installing installing
`OSPF MDR <http://www.nrl.navy.mil/itd/ncs/products/ospf-manet>`__ `OSPF MDR <http://www.nrl.navy.mil/itd/ncs/products/ospf-manet>`__
(replace `amd64` below with `i386` if needed (replace `amd64` below with `i386` if needed
to match your architecture): to match your architecture):
.. parsed-literal:: .. parsed-literal::
@ -172,7 +167,7 @@ First install the Ubuntu |UBUNTUVERSION| operating system.
:: ::
sudo apt-get install quagga sudo apt-get install quagga
* Install the CORE deb packages for Ubuntu, using a GUI that automatically * Install the CORE deb packages for Ubuntu, using a GUI that automatically
resolves dependencies (note that the absolute path to the deb file resolves dependencies (note that the absolute path to the deb file
must be used with ``software-center``): must be used with ``software-center``):
@ -181,24 +176,24 @@ First install the Ubuntu |UBUNTUVERSION| operating system.
software-center /home/user/Downloads/core-daemon\_\ |version|-|COREDEB| software-center /home/user/Downloads/core-daemon\_\ |version|-|COREDEB|
software-center /home/user/Downloads/core-gui\_\ |version|-|COREDEB2| software-center /home/user/Downloads/core-gui\_\ |version|-|COREDEB2|
or install from command-line: or install from command-line:
.. parsed-literal:: .. parsed-literal::
sudo dpkg -i core-daemon\_\ |version|-|COREDEB| sudo dpkg -i core-daemon\_\ |version|-|COREDEB|
sudo dpkg -i core-gui\_\ |version|-|COREDEB2| sudo dpkg -i core-gui\_\ |version|-|COREDEB2|
* Start the CORE daemon as root. * Start the CORE daemon as root.
:: ::
sudo /etc/init.d/core-daemon start sudo /etc/init.d/core-daemon start
* Run the CORE GUI as a normal user: * Run the CORE GUI as a normal user:
:: ::
core-gui core-gui
After running the ``core-gui`` command, a GUI should appear with a canvas After running the ``core-gui`` command, a GUI should appear with a canvas
for drawing topologies. Messages will print out on the console about for drawing topologies. Messages will print out on the console about
@ -217,7 +212,7 @@ examples below, replace with `i686` is using a 32-bit architecture. Also,
Fedora release number. Fedora release number.
* **CentOS only:** in order to install the `libev` and `tkimg` prerequisite * **CentOS only:** in order to install the `libev` and `tkimg` prerequisite
packages, you packages, you
first need to install the `EPEL <http://fedoraproject.org/wiki/EPEL>`_ repo first need to install the `EPEL <http://fedoraproject.org/wiki/EPEL>`_ repo
(Extra Packages for Enterprise Linux): (Extra Packages for Enterprise Linux):
@ -229,7 +224,7 @@ Fedora release number.
* **CentOS 7.x only:** as of this writing, the `tkimg` prerequisite package * **CentOS 7.x only:** as of this writing, the `tkimg` prerequisite package
is missing from EPEL 7.x, but the EPEL 6.x package can be manually installed is missing from EPEL 7.x, but the EPEL 6.x package can be manually installed
from from
`here <http://dl.fedoraproject.org/pub/epel/6/x86_64/repoview/tkimg.html>`_ `here <http://dl.fedoraproject.org/pub/epel/6/x86_64/repoview/tkimg.html>`_
:: ::
@ -249,7 +244,7 @@ Fedora release number.
yum install |YUMDEPS| |YUMDEPS2| yum install |YUMDEPS| |YUMDEPS2|
* **Optional (Fedora 17+):** Fedora 17 and newer have an additional * **Optional (Fedora 17+):** Fedora 17 and newer have an additional
prerequisite providing the required netem kernel modules (otherwise prerequisite providing the required netem kernel modules (otherwise
skip this step and have the package manager install it for you.) skip this step and have the package manager install it for you.)
@ -272,7 +267,7 @@ Fedora release number.
:: ::
yum install quagga yum install quagga
* Install the CORE RPM packages for Fedora and automatically resolve * Install the CORE RPM packages for Fedora and automatically resolve
dependencies: dependencies:
@ -281,14 +276,14 @@ Fedora release number.
yum localinstall python-core_|service|-|version|-|CORERPM| --nogpgcheck yum localinstall python-core_|service|-|version|-|CORERPM| --nogpgcheck
yum localinstall core-gui-|version|-|CORERPM2| --nogpgcheck yum localinstall core-gui-|version|-|CORERPM2| --nogpgcheck
or install from the command-line: or install from the command-line:
.. parsed-literal:: .. parsed-literal::
rpm -ivh python-core_|service|-|version|-|CORERPM| rpm -ivh python-core_|service|-|version|-|CORERPM|
rpm -ivh core-gui-|version|-|CORERPM2| rpm -ivh core-gui-|version|-|CORERPM2|
* Turn off SELINUX by setting ``SELINUX=disabled`` in the :file:`/etc/sysconfig/selinux` file, and adding ``selinux=0`` to the kernel line in * Turn off SELINUX by setting ``SELINUX=disabled`` in the :file:`/etc/sysconfig/selinux` file, and adding ``selinux=0`` to the kernel line in
your :file:`/etc/grub.conf` file; on Fedora 15 and newer, disable sandboxd using ``chkconfig sandbox off``; your :file:`/etc/grub.conf` file; on Fedora 15 and newer, disable sandboxd using ``chkconfig sandbox off``;
@ -304,12 +299,12 @@ Fedora release number.
systemctl start core-daemon.service systemctl start core-daemon.service
# or for CentOS: # or for CentOS:
/etc/init.d/core-daemon start /etc/init.d/core-daemon start
* Run the CORE GUI as a normal user: * Run the CORE GUI as a normal user:
:: ::
core-gui core-gui
After running the ``core-gui`` command, a GUI should appear with a canvas After running the ``core-gui`` command, a GUI should appear with a canvas
for drawing topologies. Messages will print out on the console about for drawing topologies. Messages will print out on the console about
@ -335,11 +330,11 @@ These packages are not required for normal binary package installs.
sudo apt-get install |APTDEPS| \\ sudo apt-get install |APTDEPS| \\
|APTDEPS2| \\ |APTDEPS2| \\
|APTDEPS3| |APTDEPS3|
You can obtain the CORE source from the `CORE source <http://downloads.pf.itd.nrl.navy.mil/core/source/>`_ page. Choose either a stable release version or You can obtain the CORE source from the `CORE source <http://downloads.pf.itd.nrl.navy.mil/core/source/>`_ page. Choose either a stable release version or
the development snapshot available in the `nightly_snapshots` directory. the development snapshot available in the `nightly_snapshots` directory.
The ``-j8`` argument to ``make`` will run eight simultaneous jobs, to speed up The ``-j8`` argument to ``make`` will run eight simultaneous jobs, to speed up
builds on multi-core systems. builds on multi-core systems.
.. parsed-literal:: .. parsed-literal::
@ -350,9 +345,9 @@ builds on multi-core systems.
./configure ./configure
make -j8 make -j8
sudo make install sudo make install
The CORE Manual documentation is built separately from the :file:`doc/`
The CORE Manual documentation is built separately from the :file:`doc/`
sub-directory in the source. It requires Sphinx: sub-directory in the source. It requires Sphinx:
.. parsed-literal:: .. parsed-literal::
@ -376,16 +371,16 @@ These packages are not required for normal binary package installs.
yum install |YUMDEPS| \\ yum install |YUMDEPS| \\
|YUMDEPS2| \\ |YUMDEPS2| \\
|YUMDEPS3| |YUMDEPS3|
.. NOTE:: .. NOTE::
For a minimal X11 installation, also try these packages:: For a minimal X11 installation, also try these packages::
yum install xauth xterm urw-fonts yum install xauth xterm urw-fonts
You can obtain the CORE source from the `CORE source <http://downloads.pf.itd.nrl.navy.mil/core/source/>`_ page. Choose either a stable release version or You can obtain the CORE source from the `CORE source <http://downloads.pf.itd.nrl.navy.mil/core/source/>`_ page. Choose either a stable release version or
the development snapshot available in the :file:`nightly_snapshots` directory. the development snapshot available in the :file:`nightly_snapshots` directory.
The ``-j8`` argument to ``make`` will run eight simultaneous jobs, to speed up The ``-j8`` argument to ``make`` will run eight simultaneous jobs, to speed up
builds on multi-core systems. Notice the ``configure`` flag to tell the build builds on multi-core systems. Notice the ``configure`` flag to tell the build
system that a systemd service file should be installed under Fedora. system that a systemd service file should be installed under Fedora.
@ -397,18 +392,12 @@ system that a systemd service file should be installed under Fedora.
./configure --with-startup=systemd ./configure --with-startup=systemd
make -j8 make -j8
sudo make install sudo make install
Note that the Linux RPM and Debian packages do not use the ``/usr/local``
prefix, and files are instead installed to ``/usr/sbin``, and
``/usr/lib``. This difference is a result of aligning with the directory
structure of Linux packaging systems and FreeBSD ports packaging.
Another note is that the Python distutils in Fedora Linux will install the CORE Another note is that the Python distutils in Fedora Linux will install the CORE
Python modules to :file:`/usr/lib/python2.7/site-packages/core`, instead of Python modules to :file:`/usr/lib/python2.7/site-packages/core`, instead of
using the :file:`dist-packages` directory. using the :file:`dist-packages` directory.
The CORE Manual documentation is built separately from the :file:`doc/` The CORE Manual documentation is built separately from the :file:`doc/`
sub-directory in the source. It requires Sphinx: sub-directory in the source. It requires Sphinx:
.. parsed-literal:: .. parsed-literal::
@ -438,7 +427,7 @@ CentOS/EL6 does not use the systemd service file, so the `configure` option
`--with-startup=systemd` should be omitted: `--with-startup=systemd` should be omitted:
:: ::
./configure ./configure
@ -448,12 +437,12 @@ CentOS/EL6 does not use the systemd service file, so the `configure` option
Installing from Source on SUSE Installing from Source on SUSE
------------------------------ ------------------------------
To build CORE from source on SUSE or OpenSUSE, To build CORE from source on SUSE or OpenSUSE,
use the similar instructions shown in :ref:`Installing_from_Source_on_Fedora`, use the similar instructions shown in :ref:`Installing_from_Source_on_Fedora`,
except that the following `configure` option should be used: except that the following `configure` option should be used:
:: ::
./configure --with-startup=suse ./configure --with-startup=suse
This causes a separate init script to be installed that is tailored towards SUSE systems. This causes a separate init script to be installed that is tailored towards SUSE systems.
@ -463,153 +452,6 @@ The `zypper` command is used instead of `yum`.
For OpenSUSE/Xen based installations, refer to the `README-Xen` file included For OpenSUSE/Xen based installations, refer to the `README-Xen` file included
in the CORE source. in the CORE source.
.. _Installing_from_Source_on_FreeBSD:
Installing from Source on FreeBSD
---------------------------------
.. index:: kernel patch
**Rebuilding the FreeBSD Kernel**
The FreeBSD kernel requires a small patch to allow per-node directories in the
filesystem. Also, the `VIMAGE` build option needs to be turned on to enable
jail-based network stack virtualization. The source code for the FreeBSD
kernel is located in :file:`/usr/src/sys`.
Instructions below will use the :file:`/usr/src/sys/amd64` architecture
directory, but the directory :file:`/usr/src/sys/i386` should be substituted
if you are using a 32-bit architecture.
The kernel patch is available from the CORE source tarball under core-|version|/kernel/symlinks-8.1-RELEASE.diff. This patch applies to the
FreeBSD 8.x or 9.x kernels.
.. parsed-literal::
cd /usr/src/sys
# first you can check if the patch applies cleanly using the '-C' option
patch -p1 -C < ~/core-|version|/kernel/symlinks-8.1-RELEASE.diff
# without '-C' applies the patch
patch -p1 < ~/core-|version|/kernel/symlinks-8.1-RELEASE.diff
A kernel configuration file named :file:`CORE` can be found within the source tarball: core-|version|/kernel/freebsd8-config-CORE. The config is valid for
FreeBSD 8.x or 9.x kernels.
The contents of this configuration file are shown below; you can edit it to suit your needs.
::
# this is the FreeBSD 9.x kernel configuration file for CORE
include GENERIC
ident CORE
options VIMAGE
nooptions SCTP
options IPSEC
device crypto
options IPFIREWALL
options IPFIREWALL_DEFAULT_TO_ACCEPT
The kernel configuration file can be linked or copied to the kernel source directory. Use it to configure and build the kernel:
.. parsed-literal::
cd /usr/src/sys/amd64/conf
cp ~/core-|version|/kernel/freebsd8-config-CORE CORE
config CORE
cd ../compile/CORE
make cleandepend && make depend
make -j8 && make install
Change the number 8 above to match the number of CPU cores you have times two.
Note that the ``make install`` step will move your existing kernel to
``/boot/kernel.old`` and removes that directory if it already exists. Reboot to
enable this new patched kernel.
**Building CORE from Source on FreeBSD**
Here are the prerequisite packages from the FreeBSD ports system:
::
pkg_add -r tk85
pkg_add -r libimg
pkg_add -r bash
pkg_add -r libev
pkg_add -r sudo
pkg_add -r python
pkg_add -r autotools
pkg_add -r gmake
Note that if you are installing to a bare FreeBSD system and want to SSH with X11 forwarding to that system, these packages will help:
::
pkg_add -r xauth
pkg_add -r xorg-fonts
The ``sudo`` package needs to be configured so a normal user can run the CORE
GUI using the command ``core-gui`` (opening a shell window on a node uses a
command such as ``sudo vimage n1``.)
On FreeBSD, the CORE source is built using autotools and gmake:
.. parsed-literal::
tar xzf core-|version|.tar.gz
cd core-|version|
./bootstrap.sh
./configure
gmake -j8
sudo gmake install
Build and install the ``vimage`` utility for controlling virtual images. The source can be obtained from `FreeBSD SVN <http://svn.freebsd.org/viewvc/base/head/tools/tools/vimage/>`_, or it is included with the CORE source for convenience:
.. parsed-literal::
cd core-|version|/kernel/vimage
make
make install
.. index:: FreeBSD; kernel modules
.. index:: kernel modules
.. index:: ng_wlan and ng_pipe
On FreeBSD you should also install the CORE kernel modules for wireless emulation. Perform this step after you have recompiled and installed FreeBSD kernel.
.. parsed-literal::
cd core-|version|/kernel/ng_pipe
make
sudo make install
cd ../ng_wlan
make
sudo make install
The :file:`ng_wlan` kernel module allows for the creation of WLAN nodes. This
is a modified :file:`ng_hub` Netgraph module. Instead of packets being copied
to every connected node, the WLAN maintains a hash table of connected node
pairs. Furthermore, link parameters can be specified for node pairs, in
addition to the on/off connectivity. The parameters are tagged to each packet
and sent to the connected :file:`ng_pipe` module. The :file:`ng_pipe` has been
modified to read any tagged parameters and apply them instead of its default
link effects.
The :file:`ng_wlan` also supports linking together multiple WLANs across different machines using the :file:`ng_ksocket` Netgraph node, for distributed emulation.
The Quagga routing suite is recommended for routing, The Quagga routing suite is recommended for routing,
:ref:`Quagga_Routing_Software` for installation. :ref:`Quagga_Routing_Software` for installation.
@ -624,12 +466,12 @@ Virtual networks generally require some form of routing in order to work (e.g.
to automatically populate routing tables for routing packets from one subnet to automatically populate routing tables for routing packets from one subnet
to another.) CORE builds OSPF routing protocol to another.) CORE builds OSPF routing protocol
configurations by default when the blue router configurations by default when the blue router
node type is used. The OSPF protocol is available node type is used. The OSPF protocol is available
from the `Quagga open source routing suite <http://www.quagga.net>`_. from the `Quagga open source routing suite <http://www.quagga.net>`_.
Other routing protocols are available using different Other routing protocols are available using different
node services, :ref:`Default_Services_and_Node_Types`. node services, :ref:`Default_Services_and_Node_Types`.
Quagga is not specified as a dependency for the CORE packages because Quagga is not specified as a dependency for the CORE packages because
there are two different Quagga packages that you may use: there are two different Quagga packages that you may use:
* `Quagga <http://www.quagga.net>`_ - the standard version of Quagga, suitable for static wired networks, and usually available via your distribution's package manager. * `Quagga <http://www.quagga.net>`_ - the standard version of Quagga, suitable for static wired networks, and usually available via your distribution's package manager.
@ -639,7 +481,7 @@ there are two different Quagga packages that you may use:
.. index:: MANET Designated Routers (MDR) .. index:: MANET Designated Routers (MDR)
* *
`OSPF MANET Designated Routers <http://www.nrl.navy.mil/itd/ncs/products/ospf-manet>`_ (MDR) - the Quagga routing suite with a modified version of OSPFv3, `OSPF MANET Designated Routers <http://www.nrl.navy.mil/itd/ncs/products/ospf-manet>`_ (MDR) - the Quagga routing suite with a modified version of OSPFv3,
optimized for use with mobile wireless networks. The *mdr* node type (and the MDR service) requires this variant of Quagga. optimized for use with mobile wireless networks. The *mdr* node type (and the MDR service) requires this variant of Quagga.
@ -651,26 +493,19 @@ otherwise install the standard version of Quagga using your package manager or f
Installing Quagga from Packages Installing Quagga from Packages
------------------------------- -------------------------------
To install the standard version of Quagga from packages, use your package To install the standard version of Quagga from packages, use your package manager (Linux).
manager (Linux) or the ports system (FreeBSD).
Ubuntu users: Ubuntu users:
:: ::
sudo apt-get install quagga sudo apt-get install quagga
Fedora users: Fedora users:
:: ::
yum install quagga yum install quagga
FreeBSD users:
::
pkg_add -r quagga To install the Quagga variant having OSPFv3 MDR, first download the
To install the Quagga variant having OSPFv3 MDR, first download the
appropriate package, and install using the package manager. appropriate package, and install using the package manager.
Ubuntu users: Ubuntu users:
@ -709,7 +544,7 @@ To compile Quagga to work with CORE on Linux:
--localstatedir=/var/run/quagga --localstatedir=/var/run/quagga
make make
sudo make install sudo make install
Note that the configuration directory :file:`/usr/local/etc/quagga` shown for Note that the configuration directory :file:`/usr/local/etc/quagga` shown for
Quagga above could be :file:`/etc/quagga`, if you create a symbolic link from Quagga above could be :file:`/etc/quagga`, if you create a symbolic link from
@ -723,26 +558,9 @@ If you try to run quagga after installing from source and get an error such as:
error while loading shared libraries libzebra.so.0 error while loading shared libraries libzebra.so.0
this is usually a sign that you have to run `sudo ldconfig` to refresh the this is usually a sign that you have to run `sudo ldconfig` to refresh the
cache file. cache file.
To compile Quagga to work with CORE on FreeBSD:
.. parsed-literal::
tar xzf |QVER|.tar.gz
cd |QVER|
./configure --enable-user=root --enable-group=wheel \\
--sysconfdir=/usr/local/etc/quagga --enable-vtysh \\
--localstatedir=/var/run/quagga
gmake
gmake install
On FreeBSD |BSDVERSION| you can use ``make`` or ``gmake``.
You probably want to compile Quagga from the ports system in
:file:`/usr/ports/net/quagga`.
VCORE VCORE
===== =====

View file

@ -12,8 +12,8 @@ networks. As an emulator, CORE builds a representation of a real computer
network that runs in real time, as opposed to simulation, where abstract models network that runs in real time, as opposed to simulation, where abstract models
are used. The live-running emulation can be connected to physical networks and are used. The live-running emulation can be connected to physical networks and
routers. It provides an environment for running real applications and routers. It provides an environment for running real applications and
protocols, taking advantage of virtualization provided by the Linux or FreeBSD protocols, taking advantage of virtualization provided by the Linux operating
operating systems. system.
Some of its key features are: Some of its key features are:
@ -94,8 +94,7 @@ further control.
How Does it Work? How Does it Work?
================= =================
A CORE node is a lightweight virtual machine. The CORE framework runs on Linux A CORE node is a lightweight virtual machine. The CORE framework runs on Linux.
and FreeBSD systems. The primary platform used for development is Linux.
.. index:: .. index::
single: Linux; virtualization single: Linux; virtualization
@ -104,8 +103,6 @@ and FreeBSD systems. The primary platform used for development is Linux.
single: network namespaces single: network namespaces
* :ref:`Linux` CORE uses Linux network namespace virtualization to build virtual nodes, and ties them together with virtual networks using Linux Ethernet bridging. * :ref:`Linux` CORE uses Linux network namespace virtualization to build virtual nodes, and ties them together with virtual networks using Linux Ethernet bridging.
* :ref:`FreeBSD` CORE uses jails with a network stack virtualization kernel option to build virtual nodes, and ties them together with virtual networks using BSD's Netgraph system.
.. _Linux: .. _Linux:
@ -117,9 +114,9 @@ technique used by CORE. LXC has been part of the mainline Linux kernel since
2.6.24. Recent Linux distributions such as Fedora and Ubuntu have 2.6.24. Recent Linux distributions such as Fedora and Ubuntu have
namespaces-enabled kernels out of the box, so the kernel does not need to be namespaces-enabled kernels out of the box, so the kernel does not need to be
patched or recompiled. patched or recompiled.
A namespace is created using the ``clone()`` system call. Similar A namespace is created using the ``clone()`` system call. Each namespace has
to the BSD jails, each namespace has its own process environment and private its own process environment and private network stack. Network namespaces
network stack. Network namespaces share the same filesystem in CORE. share the same filesystem in CORE.
.. index:: .. index::
single: Linux; bridging single: Linux; bridging
@ -132,56 +129,6 @@ disciplines. Ebtables is Ethernet frame filtering on Linux bridges. Wireless
networks are emulated by controlling which interfaces can send and receive with networks are emulated by controlling which interfaces can send and receive with
ebtables rules. ebtables rules.
.. _FreeBSD:
FreeBSD
-------
.. index::
single: FreeBSD; Network stack virtualization
single: FreeBSD; jails
single: FreeBSD; vimages
FreeBSD jails provide an isolated process space, a virtual environment for
running programs. Starting with FreeBSD 8.0, a new `vimage` kernel option
extends BSD jails so that each jail can have its own virtual network stack --
its own networking variables such as addresses, interfaces, routes, counters,
protocol state, socket information, etc. The existing networking algorithms and
code paths are intact but operate on this virtualized state.
Each jail plus network stack forms a lightweight virtual machine. These are
named jails or *virtual images* (or *vimages*) and are created using a the
``jail`` or ``vimage`` command. Unlike traditional virtual
machines, vimages do not feature entire operating systems running on emulated
hardware. All of the vimages will share the same processor, memory, clock, and
other system resources. Because the actual hardware is not emulated and network
packets can be passed by reference through the in-kernel Netgraph system,
vimages are quite lightweight and a single system can accommodate numerous
instances.
Virtual network stacks in FreeBSD were historically available as a patch to the
FreeBSD 4.11 and 7.0 kernels, and the VirtNet project [#f1]_ [#f2]_
added this functionality to the
mainline 8.0-RELEASE and newer kernels.
.. index::
single: FreeBSD; Netgraph
The FreeBSD Operating System kernel features a graph-based
networking subsystem named Netgraph. The netgraph(4) manual page quoted below
best defines this system:
The netgraph system provides a uniform and modular system for the
implementation of kernel objects which perform various networking functions.
The objects, known as nodes, can be arranged into arbitrarily complicated
graphs. Nodes have hooks which are used to connect two nodes together,
forming the edges in the graph. Nodes communicate along the edges to
process data, implement protocols, etc.
The aim of netgraph is to supplement rather than replace the existing
kernel networking infrastructure.
.. index:: .. index::
single: IMUNES single: IMUNES
single: VirtNet single: VirtNet
@ -201,7 +148,7 @@ The Tcl/Tk CORE GUI was originally derived from the open source
project from the University of Zagreb project from the University of Zagreb
as a custom project within Boeing Research and Technology's Network as a custom project within Boeing Research and Technology's Network
Technology research group in 2004. Since then they have developed the CORE Technology research group in 2004. Since then they have developed the CORE
framework to use not only FreeBSD but Linux virtualization, have developed a framework to use Linux virtualization, have developed a
Python framework, and made numerous user- and kernel-space developments, such Python framework, and made numerous user- and kernel-space developments, such
as support for wireless networks, IPsec, the ability to distribute emulations, as support for wireless networks, IPsec, the ability to distribute emulations,
simulation integration, and more. The IMUNES project also consists of userspace simulation integration, and more. The IMUNES project also consists of userspace
@ -226,20 +173,16 @@ CORE has been released by Boeing to the open source community under the BSD
license. If you find CORE useful for your work, please contribute back to the license. If you find CORE useful for your work, please contribute back to the
project. Contributions can be as simple as reporting a bug, dropping a line of project. Contributions can be as simple as reporting a bug, dropping a line of
encouragement or technical suggestions to the mailing lists, or can also encouragement or technical suggestions to the mailing lists, or can also
include submitting patches or maintaining aspects of the tool. For details on include submitting patches or maintaining aspects of the tool. For contributing to
contributing to CORE, please visit the CORE, please visit the
`wiki <http://code.google.com/p/coreemu/wiki/Home, wiki>`_. `CORE GitHub <https://github.com/coreemu/core>`_.
Besides this manual, there are other additional resources available online: Besides this manual, there are other additional resources available online:
* `CORE website <http://www.nrl.navy.mil/itd/ncs/products/core>`_ - main project page containing demos, downloads, and mailing list information. * `CORE website <http://www.nrl.navy.mil/itd/ncs/products/core>`_ - main project page containing demos, downloads, and mailing list information.
* `CORE supplemental website <http://code.google.com/p/coreemu/>`_ - supplemental Google Code page with a quickstart guide, wiki, bug tracker, and screenshots.
.. index:: .. index::
single: wiki single: CORE
single: CORE; wiki
The `CORE wiki <http://code.google.com/p/coreemu/wiki/Home>`_ is a good place to check for the latest documentation and tips.
Goals Goals
----- -----
@ -255,10 +198,9 @@ Non-Goals
--------- ---------
This is a list of Non-Goals, specific things that people may be interested in but are not areas that we will pursue. This is a list of Non-Goals, specific things that people may be interested in but are not areas that we will pursue.
#. Reinventing the wheel - Where possible, CORE reuses existing open source components such as virtualization, Netgraph, netem, bridging, Quagga, etc. #. Reinventing the wheel - Where possible, CORE reuses existing open source components such as virtualization, Netgraph, netem, bridging, Quagga, etc.
#. 1,000,000 nodes - While the goal of CORE is to provide efficient, scalable network emulation, there is no set goal of N number of nodes. There are realistic limits on what a machine can handle as its resources are divided amongst virtual nodes. We will continue to make things more efficient and let the user determine the right number of nodes based on available hardware and the activities each node is performing. #. 1,000,000 nodes - While the goal of CORE is to provide efficient, scalable network emulation, there is no set goal of N number of nodes. There are realistic limits on what a machine can handle as its resources are divided amongst virtual nodes. We will continue to make things more efficient and let the user determine the right number of nodes based on available hardware and the activities each node is performing.
#. Solves every problem - CORE is about emulating networking layers 3-7 using virtual network stacks in the Linux or FreeBSD operating systems. #. Solves every problem - CORE is about emulating networking layers 3-7 using virtual network stacks in Linux operating systems.
#. Hardware-specific - CORE itself is not an instantiation of hardware, a testbed, or a specific laboratory setup; it should run on commodity laptop and desktop PCs, in addition to high-end server hardware. #. Hardware-specific - CORE itself is not an instantiation of hardware, a testbed, or a specific laboratory setup; it should run on commodity laptop and desktop PCs, in addition to high-end server hardware.

View file

@ -19,7 +19,7 @@ The top question about the performance of CORE is often
* Hardware - the number and speed of processors in the computer, the available * Hardware - the number and speed of processors in the computer, the available
processor cache, RAM memory, and front-side bus speed may greatly affect processor cache, RAM memory, and front-side bus speed may greatly affect
overall performance. overall performance.
* Operating system version - Linux or FreeBSD, and the specific kernel versions * Operating system version - distribution of Linux and the specific kernel versions
used will affect overall performance. used will affect overall performance.
* Active processes - all nodes share the same CPU resources, so if one or more * Active processes - all nodes share the same CPU resources, so if one or more
nodes is performing a CPU-intensive task, overall performance will suffer. nodes is performing a CPU-intensive task, overall performance will suffer.
@ -28,8 +28,8 @@ The top question about the performance of CORE is often
* GUI usage - widgets that run periodically, mobility scenarios, and other GUI * GUI usage - widgets that run periodically, mobility scenarios, and other GUI
interactions generally consume CPU cycles that may be needed for emulation. interactions generally consume CPU cycles that may be needed for emulation.
On a typical single-CPU Xeon 3.0GHz server machine with 2GB RAM running FreeBSD On a typical single-CPU Xeon 3.0GHz server machine with 2GB RAM running Linux,
|BSDVERSION|, we have found it reasonable to run 30-75 nodes running we have found it reasonable to run 30-75 nodes running
OSPFv2 and OSPFv3 routing. On this hardware CORE can instantiate 100 or more OSPFv2 and OSPFv3 routing. On this hardware CORE can instantiate 100 or more
nodes, but at that point it becomes critical as to what each of the nodes is nodes, but at that point it becomes critical as to what each of the nodes is
doing. doing.
@ -38,7 +38,7 @@ doing.
Because this software is primarily a network emulator, the more appropriate Because this software is primarily a network emulator, the more appropriate
question is *how much network traffic can it handle?* On the same 3.0GHz server question is *how much network traffic can it handle?* On the same 3.0GHz server
described above, running FreeBSD 4.11, about 300,000 packets-per-second can be described above, running Linux, about 300,000 packets-per-second can be
pushed through the system. The number of hops and the size of the packets is pushed through the system. The number of hops and the size of the packets is
less important. The limiting factor is the number of times that the operating less important. The limiting factor is the number of times that the operating
system needs to handle a packet. The 300,000 pps figure represents the number system needs to handle a packet. The 300,000 pps figure represents the number
@ -52,9 +52,9 @@ throughput seen on the full length of the network path.
For a more detailed study of performance in CORE, refer to the following publications: For a more detailed study of performance in CORE, refer to the following publications:
* J\. Ahrenholz, T. Goff, and B. Adamson, Integration of the CORE and EMANE Network Emulators, Proceedings of the IEEE Military Communications Conference 2011, November 2011. * J\. Ahrenholz, T. Goff, and B. Adamson, Integration of the CORE and EMANE Network Emulators, Proceedings of the IEEE Military Communications Conference 2011, November 2011.
* Ahrenholz, J., Comparison of CORE Network Emulation Platforms, Proceedings of the IEEE Military Communications Conference 2010, pp. 864-869, November 2010. * Ahrenholz, J., Comparison of CORE Network Emulation Platforms, Proceedings of the IEEE Military Communications Conference 2010, pp. 864-869, November 2010.
* J\. Ahrenholz, C. Danilov, T. Henderson, and J.H. Kim, CORE: A real-time network emulator, Proceedings of IEEE MILCOM Conference, 2008. * J\. Ahrenholz, C. Danilov, T. Henderson, and J.H. Kim, CORE: A real-time network emulator, Proceedings of IEEE MILCOM Conference, 2008.

View file

@ -11,9 +11,9 @@ Using the CORE GUI
.. index:: how to use CORE .. index:: how to use CORE
CORE can be used via the GUI or :ref:`Python_Scripting`. CORE can be used via the GUI or :ref:`Python_Scripting`.
A typical emulation workflow is outlined in :ref:`emulation-workflow`. A typical emulation workflow is outlined in :ref:`emulation-workflow`.
Often the GUI is used to draw nodes and network devices on the canvas. Often the GUI is used to draw nodes and network devices on the canvas.
A Python script could also be written, that imports the CORE Python module, to configure and instantiate nodes and networks. This chapter primarily covers usage of the CORE GUI. A Python script could also be written, that imports the CORE Python module, to configure and instantiate nodes and networks. This chapter primarily covers usage of the CORE GUI.
.. _emulation-workflow: .. _emulation-workflow:
@ -24,7 +24,7 @@ A Python script could also be written, that imports the CORE Python module, to c
Emulation Workflow Emulation Workflow
CORE can be customized to perform any action at each phase depicted in :ref:`emulation-workflow`. See the *Hooks...* entry on the CORE can be customized to perform any action at each phase depicted in :ref:`emulation-workflow`. See the *Hooks...* entry on the
:ref:`Session_Menu` :ref:`Session_Menu`
for details about when these session states are reached. for details about when these session states are reached.
@ -43,13 +43,13 @@ mode. Nodes are drawn on a blank canvas using the toolbar on the left and
configured from right-click menus or by double-clicking them. The GUI does not configured from right-click menus or by double-clicking them. The GUI does not
need to be run as root. need to be run as root.
Once editing is complete, pressing the green `Start` button (or choosing `Execute` from the `Session` menu) instantiates the topology within the FreeBSD kernel and enters Execute mode. In execute mode, the user can interact with the running emulated machines by double-clicking or right-clicking on them. The editing toolbar disappears and is replaced by an execute toolbar, which provides tools while running the emulation. Pressing the red `Stop` button (or choosing `Terminate` from the `Session` menu) will destroy the running emulation and return CORE to Edit mode. Once editing is complete, pressing the green `Start` button (or choosing `Execute` from the `Session` menu) instantiates the topology within the Linux kernel and enters Execute mode. In execute mode, the user can interact with the running emulated machines by double-clicking or right-clicking on them. The editing toolbar disappears and is replaced by an execute toolbar, which provides tools while running the emulation. Pressing the red `Stop` button (or choosing `Terminate` from the `Session` menu) will destroy the running emulation and return CORE to Edit mode.
CORE can be started directly in Execute mode by specifying ``--start`` and a topology file on the command line: CORE can be started directly in Execute mode by specifying ``--start`` and a topology file on the command line:
:: ::
core-gui --start ~/.core/configs/myfile.imn core-gui --start ~/.core/configs/myfile.imn
Once the emulation is running, the GUI can be closed, and a prompt will appear asking if the emulation should be terminated. The emulation may be left running and the GUI can reconnect to an existing session at a later time. Once the emulation is running, the GUI can be closed, and a prompt will appear asking if the emulation should be terminated. The emulation may be left running and the GUI can reconnect to an existing session at a later time.
@ -62,8 +62,8 @@ There is also a **Batch** mode where CORE runs without the GUI and will instanti
:: ::
core-gui --batch ~/.core/configs/myfile.imn core-gui --batch ~/.core/configs/myfile.imn
A session running in batch mode can be accessed using the ``vcmd`` command (or ``vimage`` on FreeBSD), or the GUI can connect to the session. A session running in batch mode can be accessed using the ``vcmd`` command, or the GUI can connect to the session.
.. index:: closebatch .. index:: closebatch
@ -76,12 +76,12 @@ The session number is printed in the terminal when batch mode is started. This s
If you forget the session number, you can always start the CORE GUI and use :ref:`Session_Menu` CORE sessions dialog box. If you forget the session number, you can always start the CORE GUI and use :ref:`Session_Menu` CORE sessions dialog box.
.. NOTE:: .. NOTE::
It is quite easy to have overlapping sessions when running in batch mode. This may become a problem when control networks are employed in these sessions as there could be addressing conflicts. See :ref:`Control_Network` for remedies. It is quite easy to have overlapping sessions when running in batch mode. This may become a problem when control networks are employed in these sessions as there could be addressing conflicts. See :ref:`Control_Network` for remedies.
.. NOTE:: .. NOTE::
If you like to use batch mode, consider writing a If you like to use batch mode, consider writing a
CORE :ref:`Python script <Python_Scripting>` directly. CORE :ref:`Python script <Python_Scripting>` directly.
This enables access to the full power of the Python API. This enables access to the full power of the Python API.
The :ref:`File_Menu` has a basic `Export Python Script` option for getting The :ref:`File_Menu` has a basic `Export Python Script` option for getting
started with a GUI-designed topology. started with a GUI-designed topology.
@ -92,8 +92,7 @@ The session number is printed in the terminal when batch mode is started. This s
.. index:: root privileges .. index:: root privileges
The GUI can be run as a normal user on Linux. For FreeBSD, the GUI should be run The GUI can be run as a normal user on Linux.
as root in order to start an emulation.
.. index:: port number .. index:: port number
@ -204,7 +203,7 @@ sub-menus, which appear when you click on their group icon.
wireless nodes based on the distance between them wireless nodes based on the distance between them
* |rj45| *RJ45* - with the RJ45 Physical Interface Tool, emulated nodes can * |rj45| *RJ45* - with the RJ45 Physical Interface Tool, emulated nodes can
be linked to real physical interfaces on the Linux or FreeBSD machine; be linked to real physical interfaces;
using this tool, real networks and devices can be physically connected to using this tool, real networks and devices can be physically connected to
the live-running emulation (:ref:`RJ45_Tool`) the live-running emulation (:ref:`RJ45_Tool`)
@ -330,7 +329,7 @@ File Menu
The File menu contains options for manipulating the :file:`.imn` The File menu contains options for manipulating the :file:`.imn`
:ref:`Configuration_Files`. Generally, these menu items should not be used in :ref:`Configuration_Files`. Generally, these menu items should not be used in
Execute mode (:ref:`Modes_of_Operation`.) Execute mode (:ref:`Modes_of_Operation`.)
.. index:: New .. index:: New
@ -340,7 +339,7 @@ Execute mode (:ref:`Modes_of_Operation`.)
* *Open* - invokes the File Open dialog box for selecting a new :file:`.imn` * *Open* - invokes the File Open dialog box for selecting a new :file:`.imn`
or XML file to open. You can change the default path used for this dialog or XML file to open. You can change the default path used for this dialog
in the :ref:`Preferences` Dialog. in the :ref:`Preferences` Dialog.
.. index:: Save .. index:: Save
@ -349,16 +348,16 @@ Execute mode (:ref:`Modes_of_Operation`.)
.. index:: Save As XML .. index:: Save As XML
* *Save As XML* - invokes the Save As dialog box for selecting a new * *Save As XML* - invokes the Save As dialog box for selecting a new
:file:`.xml` file for saving the current configuration in the XML file. :file:`.xml` file for saving the current configuration in the XML file.
See :ref:`Configuration_Files`. See :ref:`Configuration_Files`.
.. index:: Save As imn .. index:: Save As imn
* *Save As imn* - invokes the Save As dialog box for selecting a new * *Save As imn* - invokes the Save As dialog box for selecting a new
:file:`.imn` :file:`.imn`
topology file for saving the current configuration. Files are saved in the topology file for saving the current configuration. Files are saved in the
*IMUNES network configuration* file format described in *IMUNES network configuration* file format described in
:ref:`Configuration_Files`. :ref:`Configuration_Files`.
.. index:: Export Python script .. index:: Export Python script
@ -376,7 +375,7 @@ Execute mode (:ref:`Modes_of_Operation`.)
.. index:: Execute Python script with options .. index:: Execute Python script with options
* *Execute Python script with options* - invokes a File Open dialog box for selecting a * *Execute Python script with options* - invokes a File Open dialog box for selecting a
Python script to run and automatically connect to. After a selection is made, Python script to run and automatically connect to. After a selection is made,
a Python Script Options dialog box is invoked to allow for command-line options to be added. a Python Script Options dialog box is invoked to allow for command-line options to be added.
The Python script must create a new CORE Session and add this session to the daemon's list of sessions The Python script must create a new CORE Session and add this session to the daemon's list of sessions
in order for this to work; see :ref:`Python_Scripting`. in order for this to work; see :ref:`Python_Scripting`.
@ -386,7 +385,7 @@ Execute mode (:ref:`Modes_of_Operation`.)
* *Open current file in editor* - this opens the current topology file in the * *Open current file in editor* - this opens the current topology file in the
``vim`` text editor. First you need to save the file. Once the file has been ``vim`` text editor. First you need to save the file. Once the file has been
edited with a text editor, you will need to reload the file to see your edited with a text editor, you will need to reload the file to see your
changes. The text editor can be changed from the :ref:`Preferences` Dialog. changes. The text editor can be changed from the :ref:`Preferences` Dialog.
.. index:: Print .. index:: Print
.. index:: printing .. index:: printing
@ -434,7 +433,7 @@ Edit Menu
* *Cut*, *Copy*, *Paste* - used to cut, copy, and paste a selection. When nodes * *Cut*, *Copy*, *Paste* - used to cut, copy, and paste a selection. When nodes
are pasted, their node numbers are automatically incremented, and existing are pasted, their node numbers are automatically incremented, and existing
links are preserved with new IP addresses assigned. Services and their links are preserved with new IP addresses assigned. Services and their
customizations are copied to the new node, but care should be taken as customizations are copied to the new node, but care should be taken as
node IP addresses have changed with possibly old addresses remaining in any node IP addresses have changed with possibly old addresses remaining in any
custom service configurations. Annotations may also be copied and pasted. custom service configurations. Annotations may also be copied and pasted.
@ -503,7 +502,7 @@ The canvas menu provides commands for adding, removing, changing, and switching
altitude reference point used to convert between geographic and Cartesian altitude reference point used to convert between geographic and Cartesian
coordinate systems. By clicking the *Save as default* option, all new coordinate systems. By clicking the *Save as default* option, all new
canvases will be created with these properties. The default canvas size can canvases will be created with these properties. The default canvas size can
also be changed in the :ref:`Preferences` dialog box. also be changed in the :ref:`Preferences` dialog box.
* *Wallpaper...* - used for setting the canvas background image, * *Wallpaper...* - used for setting the canvas background image,
:ref:`Customizing_your_Topology's_Look`. :ref:`Customizing_your_Topology's_Look`.
@ -538,12 +537,12 @@ canvas.
.. index:: hide nodes .. index:: hide nodes
* *Show hidden nodes* - reveal nodes that have been hidden. Nodes are hidden by * *Show hidden nodes* - reveal nodes that have been hidden. Nodes are hidden by
selecting one or more nodes, right-clicking one and choosing *hide*. selecting one or more nodes, right-clicking one and choosing *hide*.
.. index:: locked view .. index:: locked view
* *Locked* - toggles locked view; when the view is locked, nodes cannot be * *Locked* - toggles locked view; when the view is locked, nodes cannot be
moved around on the canvas with the mouse. This could be useful when moved around on the canvas with the mouse. This could be useful when
sharing the topology with someone and you do not expect them to change sharing the topology with someone and you do not expect them to change
things. things.
@ -585,7 +584,7 @@ The tools menu lists different utility functions.
.. index:: autorearrange selected .. index:: autorearrange selected
* *Autorearrange selected* - automatically arranges the selected nodes on the * *Autorearrange selected* - automatically arranges the selected nodes on the
canvas. canvas.
.. index:: align to grid .. index:: align to grid
@ -710,7 +709,7 @@ Here are some standard widgets:
routing protocols. A line is drawn from each router halfway to the router ID routing protocols. A line is drawn from each router halfway to the router ID
of an adjacent router. The color of the line is based on the OSPF adjacency of an adjacent router. The color of the line is based on the OSPF adjacency
state such as Two-way or Full. To learn about the different colors, see the state such as Two-way or Full. To learn about the different colors, see the
*Configure Adjacency...* menu item. The :file:`vtysh` command is used to *Configure Adjacency...* menu item. The :file:`vtysh` command is used to
dump OSPF neighbor information. dump OSPF neighbor information.
Only half of the line is drawn because each Only half of the line is drawn because each
router may be in a different adjacency state with respect to the other. router may be in a different adjacency state with respect to the other.
@ -724,11 +723,7 @@ Here are some standard widgets:
link. If the throughput exceeds a certain threshold, the link will become link. If the throughput exceeds a certain threshold, the link will become
highlighted. For wireless nodes which broadcast data to all nodes in range, highlighted. For wireless nodes which broadcast data to all nodes in range,
the throughput rate is displayed next to the node and the node will become the throughput rate is displayed next to the node and the node will become
circled if the threshold is exceeded. *Note: under FreeBSD, the circled if the threshold is exceeded.
Throughput Widget will
display "0.0 kbps" on all links that have no configured link effects, because
of the way link statistics are counted; to fix this, add a small delay or a
bandwidth limit to each link.*
.. _Observer_Widgets: .. _Observer_Widgets:
@ -810,7 +805,7 @@ and options.
of configured hooks, and buttons on the bottom left allow adding, editing, of configured hooks, and buttons on the bottom left allow adding, editing,
and removing hook scripts. The new or edit button will open a hook script and removing hook scripts. The new or edit button will open a hook script
editing window. A hook script is a shell script invoked on the host (not editing window. A hook script is a shell script invoked on the host (not
within a virtual node). within a virtual node).
The script is started at the session state specified in the drop down: The script is started at the session state specified in the drop down:
@ -818,14 +813,14 @@ and options.
* *configuration* - when the user presses the *Start* button, node, link, and * *configuration* - when the user presses the *Start* button, node, link, and
other configuration data is sent to the backend. This state is also other configuration data is sent to the backend. This state is also
reached when the user customizes a service. reached when the user customizes a service.
* *instantiation* - after * *instantiation* - after
configuration data has been sent, just before the nodes are created. configuration data has been sent, just before the nodes are created.
* *runtime* - all nodes and networks have been * *runtime* - all nodes and networks have been
built and are running. (This is the same state at which built and are running. (This is the same state at which
the previously-named *global experiment script* was run.) the previously-named *global experiment script* was run.)
* *datacollect* - the user has pressed the * *datacollect* - the user has pressed the
*Stop* button, but before services have been stopped and nodes have been *Stop* button, but before services have been stopped and nodes have been
@ -837,18 +832,18 @@ and options.
* *Reset node positions* - if you have moved nodes around * *Reset node positions* - if you have moved nodes around
using the mouse or by using a mobility module, choosing this item will reset using the mouse or by using a mobility module, choosing this item will reset
all nodes to their original position on the canvas. The node locations are all nodes to their original position on the canvas. The node locations are
remembered when you first press the Start button. remembered when you first press the Start button.
* *Emulation servers...* - invokes the CORE emulation * *Emulation servers...* - invokes the CORE emulation
servers dialog for configuring :ref:`Distributed_Emulation`. servers dialog for configuring :ref:`Distributed_Emulation`.
* *Change Sessions...* - invokes the Sessions dialog for switching between * *Change Sessions...* - invokes the Sessions dialog for switching between
different different
running sessions. This dialog is presented during startup when one or running sessions. This dialog is presented during startup when one or
more sessions are already running. more sessions are already running.
* *Options...* - presents per-session options, such as the IPv4 prefix to be * *Options...* - presents per-session options, such as the IPv4 prefix to be
used, if any, for a control network used, if any, for a control network
(see :ref:`Communicating_with_the_Host_Machine`); the ability to preserve (see :ref:`Communicating_with_the_Host_Machine`); the ability to preserve
the session directory; and an on/off switch for SDT3D support. the session directory; and an on/off switch for SDT3D support.
@ -871,7 +866,7 @@ Connecting with Physical Networks
CORE's emulated networks run in real time, so they can be connected to live CORE's emulated networks run in real time, so they can be connected to live
physical networks. The RJ45 tool and the Tunnel tool help with connecting to physical networks. The RJ45 tool and the Tunnel tool help with connecting to
the real world. These tools are available from the *Link-layer nodes* menu. the real world. These tools are available from the *Link-layer nodes* menu.
When connecting two or more CORE emulations together, MAC address collisions When connecting two or more CORE emulations together, MAC address collisions
should be avoided. CORE automatically assigns MAC addresses to interfaces when should be avoided. CORE automatically assigns MAC addresses to interfaces when
@ -893,7 +888,7 @@ with the CORE nodes in real time.
The main drawback is that one physical interface is required for each The main drawback is that one physical interface is required for each
connection. When the physical interface is assigned to CORE, it may not be used connection. When the physical interface is assigned to CORE, it may not be used
for anything else. Another consideration is that the computer or network that for anything else. Another consideration is that the computer or network that
you are connecting to must be co-located with the CORE machine. you are connecting to must be co-located with the CORE machine.
To place an RJ45 connection, click on the *Link-layer nodes* toolbar and select To place an RJ45 connection, click on the *Link-layer nodes* toolbar and select
the *RJ45 Tool* from the submenu. Click on the canvas near the node you want to the *RJ45 Tool* from the submenu. Click on the canvas near the node you want to
@ -904,8 +899,8 @@ physical interface. A list of available interfaces will be shown, and one may
be selected by double-clicking its name in the list, or an interface name may be selected by double-clicking its name in the list, or an interface name may
be entered into the text box. be entered into the text box.
.. NOTE:: .. NOTE::
When you press the Start button to instantiate your topology, the When you press the Start button to instantiate your topology, the
interface assigned to the RJ45 will be connected to the CORE topology. The interface assigned to the RJ45 will be connected to the CORE topology. The
interface can no longer be used by the system. For example, if there was an interface can no longer be used by the system. For example, if there was an
IP address assigned to the physical interface before execution, the address IP address assigned to the physical interface before execution, the address
@ -925,7 +920,7 @@ physical ports are available, but the (e.g. switching) hardware connected to
the physical port must support the VLAN tagging, and the available bandwidth the physical port must support the VLAN tagging, and the available bandwidth
will be shared. will be shared.
You need to create separate VLAN virtual devices on the Linux or FreeBSD host, You need to create separate VLAN virtual devices on the Linux host,
and then assign these devices to RJ45 nodes inside of CORE. The VLANning is and then assign these devices to RJ45 nodes inside of CORE. The VLANning is
actually performed outside of CORE, so when the CORE emulated node receives a actually performed outside of CORE, so when the CORE emulated node receives a
packet, the VLAN tag will already be removed. packet, the VLAN tag will already be removed.
@ -953,15 +948,15 @@ Tunneling can be helpful when the number of physical interfaces is limited or
when the peer is located on a different network. Also a physical interface does when the peer is located on a different network. Also a physical interface does
not need to be dedicated to CORE as with the RJ45 tool. not need to be dedicated to CORE as with the RJ45 tool.
The peer GRE tunnel endpoint may be another CORE machine or a (Linux, FreeBSD, The peer GRE tunnel endpoint may be another CORE machine or another
etc.) host that supports GRE tunneling. When placing a Tunnel node, initially host that supports GRE tunneling. When placing a Tunnel node, initially
the node will display "UNASSIGNED". This text should be replaced with the IP the node will display "UNASSIGNED". This text should be replaced with the IP
address of the tunnel peer. This is the IP address of the other CORE machine or address of the tunnel peer. This is the IP address of the other CORE machine or
physical machine, not an IP address of another virtual node. physical machine, not an IP address of another virtual node.
.. NOTE:: .. NOTE::
Be aware of possible MTU issues with GRE devices. The *gretap* device Be aware of possible MTU issues with GRE devices. The *gretap* device
has an interface MTU of 1,458 bytes; when joined to a Linux bridge, the has an interface MTU of 1,458 bytes; when joined to a Linux bridge, the
bridge's MTU bridge's MTU
becomes 1,458 bytes. The Linux bridge will not perform fragmentation for becomes 1,458 bytes. The Linux bridge will not perform fragmentation for
large packets if other bridge ports have a higher MTU such as 1,500 bytes. large packets if other bridge ports have a higher MTU such as 1,500 bytes.
@ -977,7 +972,7 @@ used.
.. index:: ip link command .. index:: ip link command
Here are example commands for building the other end of a tunnel on a Linux Here are example commands for building the other end of a tunnel on a Linux
machine. In this example, a router in CORE has the virtual address machine. In this example, a router in CORE has the virtual address
``10.0.0.1/24`` and the CORE host machine has the (real) address ``10.0.0.1/24`` and the CORE host machine has the (real) address
``198.51.100.34/24``. The Linux box ``198.51.100.34/24``. The Linux box
that will connect with the CORE machine is reachable over the (real) network that will connect with the CORE machine is reachable over the (real) network
@ -989,7 +984,7 @@ an address from the subnet of the virtual router node,
``10.0.0.2/24``. ``10.0.0.2/24``.
:: ::
# these commands are run on the tunnel peer # these commands are run on the tunnel peer
sudo ip link add gt0 type gretap remote 198.51.100.34 local 198.51.100.76 key 1 sudo ip link add gt0 type gretap remote 198.51.100.34 local 198.51.100.76 key 1
sudo ip addr add 10.0.0.2/24 dev gt0 sudo ip addr add 10.0.0.2/24 dev gt0
@ -1053,7 +1048,7 @@ the node, and SSH with X11 forwarding can be used from the host to the node:
ssh -X 172.16.0.5 xclock ssh -X 172.16.0.5 xclock
Note that the :file:`coresendmsg` utility can be used for a node to send Note that the :file:`coresendmsg` utility can be used for a node to send
messages to the CORE daemon running on the host (if the ``listenaddr = 0.0.0.0`` messages to the CORE daemon running on the host (if the ``listenaddr = 0.0.0.0``
is set in the :file:`/etc/core/core.conf` file) to interact with the running is set in the :file:`/etc/core/core.conf` file) to interact with the running
emulation. For example, a node may move itself or other nodes, or change emulation. For example, a node may move itself or other nodes, or change
its icon based on some node state. its icon based on some node state.
@ -1108,7 +1103,7 @@ Wired Networks
Wired networks are created using the *Link Tool* to draw a link between two Wired networks are created using the *Link Tool* to draw a link between two
nodes. This automatically draws a red line representing an Ethernet link and nodes. This automatically draws a red line representing an Ethernet link and
creates new interfaces on network-layer nodes. creates new interfaces on network-layer nodes.
.. index:: link configuration .. index:: link configuration
@ -1124,12 +1119,11 @@ link, affecting its display.
.. index:: lanswitch .. index:: lanswitch
Link-layer nodes are provided for modeling wired networks. These do not create Link-layer nodes are provided for modeling wired networks. These do not create
a separate network stack when instantiated, but are implemented using bridging a separate network stack when instantiated, but are implemented using Linux bridging.
(Linux) or Netgraph nodes (FreeBSD). These are the hub, switch, and wireless These are the hub, switch, and wireless LAN nodes. The hub copies each packet from
LAN nodes. The hub copies each packet from the incoming link to every connected the incoming link to every connected link, while the switch behaves more like an
link, while the switch behaves more like an Ethernet switch and keeps track of Ethernet switch and keeps track of the Ethernet address of the connected peer,
the Ethernet address of the connected peer, forwarding unicast traffic only to forwarding unicast traffic only to the appropriate ports.
the appropriate ports.
The wireless LAN (WLAN) is covered in the next section. The wireless LAN (WLAN) is covered in the next section.
@ -1158,13 +1152,13 @@ on platform. See the table below for a brief overview of wireless model types.
============= ===================== ======== ================================================================== ============= ===================== ======== ==================================================================
Model Type Supported Platform(s) Fidelity Description Model Type Supported Platform(s) Fidelity Description
============= ===================== ======== ================================================================== ============= ===================== ======== ==================================================================
Basic on/off Linux, FreeBSD Low Linux Ethernet bridging with ebtables (Linux) or ng_wlan (FreeBSD) Basic on/off Linux Low Linux Ethernet bridging with ebtables
EMANE Plug-in Linux High TAP device connected to EMANE emulator with pluggable MAC and PHY radio types EMANE Plug-in Linux High TAP device connected to EMANE emulator with pluggable MAC and PHY radio types
============= ===================== ======== ================================================================== ============= ===================== ======== ==================================================================
To quickly build a wireless network, you can first place several router nodes To quickly build a wireless network, you can first place several router nodes
onto the canvas. If you have the onto the canvas. If you have the
:ref:`Quagga MDR software <Quagga_Routing_Software>` installed, it is :ref:`Quagga MDR software <Quagga_Routing_Software>` installed, it is
recommended that you use the *mdr* node type for reduced routing overhead. Next recommended that you use the *mdr* node type for reduced routing overhead. Next
choose the *wireless LAN* from the *Link-layer nodes* submenu. First set the choose the *wireless LAN* from the *Link-layer nodes* submenu. First set the
@ -1198,8 +1192,6 @@ dragging them, and wireless links will be dynamically made or broken.
The *EMANE* tab lists available EMANE models to use for wireless networking. The *EMANE* tab lists available EMANE models to use for wireless networking.
See the :ref:`EMANE` chapter for details on using EMANE. See the :ref:`EMANE` chapter for details on using EMANE.
On FreeBSD, the WLAN node is realized using the *ng_wlan* Netgraph node.
.. _Mobility_Scripting: .. _Mobility_Scripting:
Mobility Scripting Mobility Scripting
@ -1213,7 +1205,7 @@ Mobility Scripting
.. index:: mobility scripting .. index:: mobility scripting
CORE has a few ways to script mobility. CORE has a few ways to script mobility.
* ns-2 script - the script specifies either absolute positions * ns-2 script - the script specifies either absolute positions
or waypoints with a velocity. Locations are given with Cartesian coordinates. or waypoints with a velocity. Locations are given with Cartesian coordinates.
@ -1226,7 +1218,7 @@ CORE has a few ways to script mobility.
For the first method, you can create a mobility script using a text For the first method, you can create a mobility script using a text
editor, or using a tool such as `BonnMotion <http://net.cs.uni-bonn.de/wg/cs/applications/bonnmotion/>`_, and associate the script with one of the wireless editor, or using a tool such as `BonnMotion <http://net.cs.uni-bonn.de/wg/cs/applications/bonnmotion/>`_, and associate the script with one of the wireless
using the WLAN configuration dialog box. Click the *ns-2 mobility script...* using the WLAN configuration dialog box. Click the *ns-2 mobility script...*
button, and set the *mobility script file* field in the resulting *ns2script* button, and set the *mobility script file* field in the resulting *ns2script*
configuration dialog. configuration dialog.
@ -1254,11 +1246,11 @@ The format of an ns-2 mobility script looks like:
$node_(2) set Y_ 240.0 $node_(2) set Y_ 240.0
$node_(2) set Z_ 0.00 $node_(2) set Z_ 0.00
$ns_ at 1.00 "$node_(2) setdest 130.0 280.0 15.0" $ns_ at 1.00 "$node_(2) setdest 130.0 280.0 15.0"
The first three lines set an initial position for node 2. The last line in the The first three lines set an initial position for node 2. The last line in the
above example causes node 2 to move towards the destination `(130, 280)` at above example causes node 2 to move towards the destination `(130, 280)` at
speed `15`. All units are screen coordinates, with speed in units per second. speed `15`. All units are screen coordinates, with speed in units per second.
The The
total script time is learned after all nodes have reached their waypoints. total script time is learned after all nodes have reached their waypoints.
Initially, the time slider in the mobility script dialog will not be Initially, the time slider in the mobility script dialog will not be
@ -1305,13 +1297,12 @@ Distributed Emulation
A large emulation scenario can be deployed on multiple emulation servers and A large emulation scenario can be deployed on multiple emulation servers and
controlled by a single GUI. The GUI, representing the entire topology, can be controlled by a single GUI. The GUI, representing the entire topology, can be
run on one of the emulation servers or on a separate machine. Emulations can be run on one of the emulation servers or on a separate machine. Emulations can be
distributed on Linux, while tunneling support has not been added yet for distributed on Linux.
FreeBSD.
Each machine that will act as an emulation server needs to have CORE installed. Each machine that will act as an emulation server needs to have CORE installed.
It is not important to have the GUI component but the CORE Python daemon It is not important to have the GUI component but the CORE Python daemon
:file:`core-daemon` needs to be installed. Set the ``listenaddr`` line in the :file:`core-daemon` needs to be installed. Set the ``listenaddr`` line in the
:file:`/etc/core/core.conf` configuration file so that the CORE Python :file:`/etc/core/core.conf` configuration file so that the CORE Python
daemon will respond to commands from other servers: daemon will respond to commands from other servers:
:: ::
@ -1320,7 +1311,7 @@ daemon will respond to commands from other servers:
pidfile = /var/run/core-daemon.pid pidfile = /var/run/core-daemon.pid
logfile = /var/log/core-daemon.log logfile = /var/log/core-daemon.log
listenaddr = 0.0.0.0 listenaddr = 0.0.0.0
The ``listenaddr`` should be set to the address of the interface that should The ``listenaddr`` should be set to the address of the interface that should
receive CORE API control commands from the other servers; setting ``listenaddr receive CORE API control commands from the other servers; setting ``listenaddr
@ -1356,19 +1347,19 @@ Servers are configured by choosing *Emulation servers...* from the *Session*
menu. Servers parameters are configured in the list below and stored in a menu. Servers parameters are configured in the list below and stored in a
*servers.conf* file for use in different scenarios. The IP address and port of *servers.conf* file for use in different scenarios. The IP address and port of
the server must be specified. The name of each server will be saved in the the server must be specified. The name of each server will be saved in the
topology file as each node's location. topology file as each node's location.
.. NOTE:: .. NOTE::
The server that the GUI connects with The server that the GUI connects with
is referred to as the master server. is referred to as the master server.
The user needs to assign nodes to emulation servers in the scenario. Making no The user needs to assign nodes to emulation servers in the scenario. Making no
assignment means the node will be emulated on the master server assignment means the node will be emulated on the master server
In the configuration window of every node, a drop-down box located between In the configuration window of every node, a drop-down box located between
the *Node name* and the *Image* button will select the name of the emulation the *Node name* and the *Image* button will select the name of the emulation
server. By default, this menu shows *(none)*, indicating that the node will server. By default, this menu shows *(none)*, indicating that the node will
be emulated locally on the master. When entering Execute mode, the CORE GUI be emulated locally on the master. When entering Execute mode, the CORE GUI
will deploy the node on its assigned emulation server. will deploy the node on its assigned emulation server.
Another way to assign emulation servers is to select one or more nodes using Another way to assign emulation servers is to select one or more nodes using
@ -1395,7 +1386,7 @@ If there is a link between two nodes residing on different servers, the GUI
will draw the link with a dashed line, and automatically create necessary will draw the link with a dashed line, and automatically create necessary
tunnels between the nodes when executed. Care should be taken to arrange the tunnels between the nodes when executed. Care should be taken to arrange the
topology such that the number of tunnels is minimized. The tunnels carry data topology such that the number of tunnels is minimized. The tunnels carry data
between servers to connect nodes as specified in the topology. between servers to connect nodes as specified in the topology.
These tunnels are created using GRE tunneling, similar to the These tunnels are created using GRE tunneling, similar to the
:ref:`Tunnel_Tool`. :ref:`Tunnel_Tool`.
@ -1561,7 +1552,7 @@ service. Generally they send a kill signal to the running process using the
*kill* or *killall* commands. If the service does not terminate *kill* or *killall* commands. If the service does not terminate
the running processes using a shutdown command, the processes will be killed the running processes using a shutdown command, the processes will be killed
when the *vnoded* daemon is terminated (with *kill -9*) and when the *vnoded* daemon is terminated (with *kill -9*) and
the namespace destroyed. It is a good practice to the namespace destroyed. It is a good practice to
specify shutdown commands, which will allow for proper process termination, and specify shutdown commands, which will allow for proper process termination, and
for run-time control of stopping and restarting services. for run-time control of stopping and restarting services.
@ -1606,7 +1597,7 @@ in the :file:`/etc/core/core.conf` configuration file. A sample is provided in
the :file:`myservices/` directory. the :file:`myservices/` directory.
.. NOTE:: .. NOTE::
The directory name used in `custom_services_dir` should be unique and The directory name used in `custom_services_dir` should be unique and
should not correspond to should not correspond to
any existing Python module name. For example, don't use the name `subprocess` any existing Python module name. For example, don't use the name `subprocess`
or `services`. or `services`.
@ -1641,7 +1632,7 @@ create a bridge or namespace, or the failure to launch EMANE processes for an
EMANE-based network. EMANE-based network.
Clicking on an exception displays details for that Clicking on an exception displays details for that
exception. If a node number is specified, that node is highlighted on the exception. If a node number is specified, that node is highlighted on the
canvas when the exception is selected. The exception source is a text string canvas when the exception is selected. The exception source is a text string
to help trace where the exception occurred; "service:UserDefined" for example, to help trace where the exception occurred; "service:UserDefined" for example,
would appear for a failed validation command with the UserDefined service. would appear for a failed validation command with the UserDefined service.
@ -1654,7 +1645,7 @@ list and for viewing the CORE daemon and node log files.
.. index:: CEL batch mode .. index:: CEL batch mode
.. NOTE:: .. NOTE::
In batch mode, exceptions received from the CORE daemon are displayed on In batch mode, exceptions received from the CORE daemon are displayed on
the console. the console.
.. _Configuration_Files: .. _Configuration_Files:
@ -1668,16 +1659,16 @@ Configuration Files
Configurations are saved to :file:`xml` or :file:`.imn` topology files using Configurations are saved to :file:`xml` or :file:`.imn` topology files using
the *File* menu. You the *File* menu. You
can easily edit these files with a text editor. can easily edit these files with a text editor.
Any time you edit the topology Any time you edit the topology
file, you will need to stop the emulation if it were running and reload the file, you will need to stop the emulation if it were running and reload the
file. file.
The :file:`.xml` `file schema is specified by NRL <http://www.nrl.navy.mil/itd/ncs/products/mnmtools>`_ and there are two versions to date: The :file:`.xml` `file schema is specified by NRL <http://www.nrl.navy.mil/itd/ncs/products/mnmtools>`_ and there are two versions to date:
version 0.0 and version 1.0, version 0.0 and version 1.0,
with 1.0 as the current default. CORE can open either XML version. However, the with 1.0 as the current default. CORE can open either XML version. However, the
xmlfilever line in :file:`/etc/core/core.conf` controls the version of the XML file xmlfilever line in :file:`/etc/core/core.conf` controls the version of the XML file
that CORE will create. that CORE will create.
.. index:: Scenario Plan XML .. index:: Scenario Plan XML
@ -1685,7 +1676,7 @@ In version 1.0, the XML file is also referred to as the Scenario Plan. The Scena
made up of the following: made up of the following:
* `Network Plan` - describes nodes, hosts, interfaces, and the networks to * `Network Plan` - describes nodes, hosts, interfaces, and the networks to
which they belong. which they belong.
* `Motion Plan` - describes position and motion patterns for nodes in an * `Motion Plan` - describes position and motion patterns for nodes in an
emulation. emulation.
@ -1694,7 +1685,7 @@ made up of the following:
* `Visualization Plan` - meta-data that is not part of the NRL XML schema but * `Visualization Plan` - meta-data that is not part of the NRL XML schema but
used only by CORE. For example, GUI options, canvas and annotation info, etc. used only by CORE. For example, GUI options, canvas and annotation info, etc.
are contained here. are contained here.
* `Test Bed Mappings` - describes mappings of nodes, interfaces and EMANE modules in the scenario to * `Test Bed Mappings` - describes mappings of nodes, interfaces and EMANE modules in the scenario to
test bed hardware. test bed hardware.
CORE includes Test Bed Mappings in XML files that are saved while the scenario is running. CORE includes Test Bed Mappings in XML files that are saved while the scenario is running.
@ -1710,7 +1701,7 @@ indentation is one tab character.
.. tip:: .. tip::
There are several topology examples included with CORE in There are several topology examples included with CORE in
the :file:`configs/` directory. the :file:`configs/` directory.
This directory can be found in :file:`~/.core/configs`, or This directory can be found in :file:`~/.core/configs`, or
installed to the filesystem installed to the filesystem
under :file:`/usr[/local]/share/examples/configs`. under :file:`/usr[/local]/share/examples/configs`.

View file

@ -33,8 +33,6 @@ CONFIG_FILES = configs/sample1.imn configs/sample1.scen \
configs/sample9-vpn.imn \ configs/sample9-vpn.imn \
configs/sample10-kitchen-sink.imn configs/sample10-kitchen-sink.imn
OTHER_FILES = core-bsd-cleanup.sh
# #
# CORE GUI script (/usr/local/bin/core-gui) # CORE GUI script (/usr/local/bin/core-gui)
# #
@ -44,7 +42,7 @@ dist_bin_SCRIPTS = core-gui
# Tcl/Tk scripts (/usr/local/lib/core) # Tcl/Tk scripts (/usr/local/lib/core)
# #
coredir = $(CORE_LIB_DIR) coredir = $(CORE_LIB_DIR)
dist_core_DATA = $(TCL_FILES) dist_core_DATA = $(TCL_FILES)
dist_core_SCRIPTS = $(OTHER_FILES) dist_core_SCRIPTS = $(OTHER_FILES)
# #
@ -57,7 +55,7 @@ dist_coreaddons_DATA = $(ADDONS_FILES)
# Sample configs (/usr/local/share/core/examples/configs) # Sample configs (/usr/local/share/core/examples/configs)
# #
coreconfigsdir = $(datadir)/core/examples/configs coreconfigsdir = $(datadir)/core/examples/configs
dist_coreconfigs_DATA = $(CONFIG_FILES) dist_coreconfigs_DATA = $(CONFIG_FILES)
dist-hook: dist-hook:
rm -rf $(distdir)/addons/.svn rm -rf $(distdir)/addons/.svn

View file

@ -135,7 +135,7 @@ proc receiveMessage { channel } {
# #
# Open an API socket to the specified server:port, prompt user for retry # Open an API socket to the specified server:port, prompt user for retry
# if specified; set the readable file event and parameters; # if specified; set the readable file event and parameters;
# returns the channel name or -1 on error. # returns the channel name or -1 on error.
# #
proc openAPIChannel { server port retry } { proc openAPIChannel { server port retry } {
@ -186,7 +186,7 @@ proc openAPIChannel { server port retry } {
# now we have a valid socket, set up encoding and receive event # now we have a valid socket, set up encoding and receive event
fconfigure $s -blocking 0 -encoding binary -translation { binary binary } \ fconfigure $s -blocking 0 -encoding binary -translation { binary binary } \
-buffering full -buffersize 4096 -buffering full -buffersize 4096
fileevent $s readable [list receiveMessage $s] fileevent $s readable [list receiveMessage $s]
return $s return $s
} }
@ -299,7 +299,7 @@ proc parseNodeMessage { data len flags } {
# verbose debugging # verbose debugging
#puts "tlv type=$type length=$length pad=$pad current=$current" #puts "tlv type=$type length=$length pad=$pad current=$current"
incr current 2 incr current 2
if {![info exists typenames($type)] } { ;# unknown TLV type if {![info exists typenames($type)] } { ;# unknown TLV type
if { $prmsg } { puts -nonewline "unknown=$type," } if { $prmsg } { puts -nonewline "unknown=$type," }
incr current $length incr current $length
@ -352,11 +352,11 @@ proc parseNodeMessage { data len flags } {
} else { } else {
set exists true set exists true
} }
if { $vals(name) == "" } {; # make sure there is a node name if { $vals(name) == "" } {; # make sure there is a node name
set name $node set name $node
if { $exists } { set name [getNodeName $node] } if { $exists } { set name [getNodeName $node] }
array set vals [list name $name] array set vals [list name $name]
} }
if { $exists } { if { $exists } {
if { $flags == 1 } { if { $flags == 1 } {
@ -384,9 +384,7 @@ proc parseNodeMessage { data len flags } {
set wlans_needing_update { } set wlans_needing_update { }
if { $vals(emuid) != -1 } { if { $vals(emuid) != -1 } {
# For Linux (FreeBSD populates ngnodeidmap in l3node.instantiate/ # For Linux populate ngnodeidmap for later use with wireless; it is treated as
# buildInterface when the netgraph ID is known)
# populate ngnodeidmap for later use with wireless; it is treated as
# a hex value string (without the leading "0x") # a hex value string (without the leading "0x")
global ngnodeidmap global ngnodeidmap
foreach wlan [findWlanNodes $node] { foreach wlan [findWlanNodes $node] {
@ -484,7 +482,7 @@ proc apiNodeCreate { node vals_ref } {
return return
} }
set canv "c$canv" set canv "c$canv"
if { [lsearch $canvas_list $canv] < 0 && $canv == "c0" } { if { [lsearch $canvas_list $canv] < 0 && $canv == "c0" } {
# special case -- support old imn files with Canvas0 # special case -- support old imn files with Canvas0
global $canv global $canv
lappend canvas_list $canv lappend canvas_list $canv
@ -787,12 +785,12 @@ proc apiLinkAddModify { node1 node2 vals_ref add } {
updateLinkGuiAttr $wired_link $vals(guiattr) updateLinkGuiAttr $wired_link $vals(guiattr)
return return
# if add flag is set and a wired link already exists, assume wlan linkage # if add flag is set and a wired link already exists, assume wlan linkage
# special case: rj45 model=1 means link via wireless # special case: rj45 model=1 means link via wireless
} elseif {[nodeType $node1] == "rj45" || [nodeType $node2] == "rj45"} { } elseif {[nodeType $node1] == "rj45" || [nodeType $node2] == "rj45"} {
if { [nodeType $node1] == "rj45" } { if { [nodeType $node1] == "rj45" } {
set rj45node $node1; set othernode $node2; set rj45node $node1; set othernode $node2;
} else { set rj45node $node2; set othernode $node1; } } else { set rj45node $node2; set othernode $node1; }
if { [netconfFetchSection $rj45node model] == 1 } { if { [netconfFetchSection $rj45node model] == 1 } {
set wlan [findWlanNodes $othernode] set wlan [findWlanNodes $othernode]
if {$wlan != ""} {newGUILink $wlan $rj45node};# link rj4node to wlan if {$wlan != ""} {newGUILink $wlan $rj45node};# link rj4node to wlan
} }
@ -1034,7 +1032,7 @@ proc parseRegMessage { data len flags channel } {
# TLV header # TLV header
if { [binary scan $data @${current}cc type length] != 2 } { if { [binary scan $data @${current}cc type length] != 2 } {
puts "TLV header error" puts "TLV header error"
break break
} }
set length [expr {$length & 0xFF}]; # convert signed to unsigned set length [expr {$length & 0xFF}]; # convert signed to unsigned
if { $length == 0 } { if { $length == 0 } {
@ -1078,9 +1076,9 @@ proc parseRegMessage { data len flags channel } {
if { $session != "" } { if { $session != "" } {
# The channel passed to here is soon after discarded for # The channel passed to here is soon after discarded for
# sessions that are started from XML or Python scripts. This causes # sessions that are started from XML or Python scripts. This causes
# an exception in the GUI when responding back to daemon if the # an exception in the GUI when responding back to daemon if the
# response is sent after the channel has been destroyed. Setting # response is sent after the channel has been destroyed. Setting
# the channel to -1 basically disables the GUI response to the daemon, # the channel to -1 basically disables the GUI response to the daemon,
# but it turns out the daemon does not need the response anyway. # but it turns out the daemon does not need the response anyway.
set channel -1 set channel -1
# assume session string only contains one session number # assume session string only contains one session number
@ -1432,7 +1430,7 @@ proc parseEventMessage { data len flags channel } {
2 { 2 {
incr current $pad incr current $pad
binary scan $data @${current}I eventtype binary scan $data @${current}I eventtype
if { $prmsg == 1} { if { $prmsg == 1} {
set typestr "" set typestr ""
foreach t [array names eventtypes] { foreach t [array names eventtypes] {
if { $eventtypes($t) == $eventtype } { if { $eventtypes($t) == $eventtype } {
@ -1493,7 +1491,7 @@ proc parseEventMessage { data len flags channel } {
set name [lindex [getEmulPlugin "*"] 0] set name [lindex [getEmulPlugin "*"] 0]
if { [getAssignedRemoteServers] == "" } { if { [getAssignedRemoteServers] == "" } {
# start a new session if not distributed # start a new session if not distributed
# otherwise we need to allow time for node delete messages # otherwise we need to allow time for node delete messages
# from other servers # from other servers
pluginConnect $name disconnect 1 pluginConnect $name disconnect 1
pluginConnect $name connect 1 pluginConnect $name connect 1
@ -1529,7 +1527,7 @@ proc parseSessionMessage { data len flags channel } {
set typelength [parseTLVHeader $data current] set typelength [parseTLVHeader $data current]
set type [lindex $typelength 0] set type [lindex $typelength 0]
set length [lindex $typelength 1] set length [lindex $typelength 1]
if { $length == 0 || $length == "" } { if { $length == 0 || $length == "" } {
puts "warning: zero-length TLV, discarding remainder of message!" puts "warning: zero-length TLV, discarding remainder of message!"
break break
} }
@ -1737,7 +1735,7 @@ proc sendNodePosMessage { channel node nodeid x y wlanid force } {
if {$wlanid > -1} { incr len 8 } if {$wlanid > -1} { incr len 8 }
if {$force == 1 } { set crit 0x4 } else { set crit 0x0 } if {$force == 1 } { set crit 0x4 } else { set crit 0x0 }
#puts "sending [expr $len+4] bytes: $nodeid $x $y $wlanid" #puts "sending [expr $len+4] bytes: $nodeid $x $y $wlanid"
if { $prmsg == 1 } { if { $prmsg == 1 } {
puts -nonewline ">NODE(flags=$crit,$node,x=$x,y=$y" } puts -nonewline ">NODE(flags=$crit,$node,x=$x,y=$y" }
set msg [binary format ccSc2sIc2Sc2S \ set msg [binary format ccSc2sIc2Sc2S \
1 $crit $len \ 1 $crit $len \
@ -1805,8 +1803,8 @@ proc sendNodeAddMessage { channel node } {
} else { } else {
set canv "" set canv ""
} }
# services # services
set svc [getNodeServices $node false] set svc [getNodeServices $node false]
set svc [join $svc "|"] set svc [join $svc "|"]
set svc_len [string length $svc] set svc_len [string length $svc]
@ -1854,7 +1852,7 @@ proc sendNodeAddMessage { channel node } {
set mac [join [split $macstr ":"] ""] set mac [join [split $macstr ":"] ""]
puts -nonewline $channel [binary format c2x2W {0x5 8} 0x$mac] puts -nonewline $channel [binary format c2x2W {0x5 8} 0x$mac]
} }
# IPv6 address # IPv6 address
if { $ipv6 != 0 } { if { $ipv6 != 0 } {
if { $prmsg == 1 } { puts -nonewline "$ipv6str," } if { $prmsg == 1 } { puts -nonewline "$ipv6str," }
@ -1943,7 +1941,7 @@ proc sendNodeDelMessage { channel node } {
proc sendLinkMessage { channel link type {sendboth true} } { proc sendLinkMessage { channel link type {sendboth true} } {
global showAPI global showAPI
set prmsg $showAPI set prmsg $showAPI
set node1 [lindex [linkPeers $link] 0] set node1 [lindex [linkPeers $link] 0]
set node2 [lindex [linkPeers $link] 1] set node2 [lindex [linkPeers $link] 1]
set if1 [ifcByPeer $node1 $node2]; set if2 [ifcByPeer $node2 $node1] set if1 [ifcByPeer $node1 $node2]; set if2 [ifcByPeer $node2 $node1]
@ -2207,7 +2205,7 @@ proc getIfcAddrs { node ifc ipv4p ipv6p macp ipv4maskp ipv6maskp lenp } {
# IPv4 address # IPv4 address
set ipv4str [getIfcIPv4addr $node $ifc] set ipv4str [getIfcIPv4addr $node $ifc]
if {$ipv4str != ""} { if {$ipv4str != ""} {
set ipv4 [lindex [split $ipv4str /] 0] set ipv4 [lindex [split $ipv4str /] 0]
if { [info exists ipv4mask ] } { if { [info exists ipv4mask ] } {
set ipv4mask [lindex [split $ipv4str / ] 1] set ipv4mask [lindex [split $ipv4str / ] 1]
@ -2222,7 +2220,7 @@ proc getIfcAddrs { node ifc ipv4p ipv6p macp ipv4maskp ipv6maskp lenp } {
# IPv6 address # IPv6 address
set ipv6str [getIfcIPv6addr $node $ifc] set ipv6str [getIfcIPv6addr $node $ifc]
if {$ipv6str != ""} { if {$ipv6str != ""} {
set ipv6 [lindex [split $ipv6str /] 0] set ipv6 [lindex [split $ipv6str /] 0]
if { [info exists ipv6mask ] } { if { [info exists ipv6mask ] } {
set ipv6mask [lindex [split $ipv6str / ] 1] set ipv6mask [lindex [split $ipv6str / ] 1]
@ -2248,7 +2246,7 @@ proc getIfcAddrs { node ifc ipv4p ipv6p macp ipv4maskp ipv6maskp lenp } {
# #
# Register Message: (registration types) # Register Message: (registration types)
# This is a simple Register Message, types is an array of # This is a simple Register Message, types is an array of
# <module TLV, string> tuples. # <module TLV, string> tuples.
proc sendRegMessage { channel flags types_list } { proc sendRegMessage { channel flags types_list } {
global showAPI regtypes global showAPI regtypes
@ -2361,7 +2359,7 @@ proc sendConfRequestMessage { channel node model flags netid opaque } {
set msg4 [binary format c2sI {0x23 4} 0 0x$netid ] set msg4 [binary format c2sI {0x23 4} 0 0x$netid ]
} }
#catch {puts -nonewline $channel $msg1$model$model_pad$msg2$msg3$msg4$msg5} #catch {puts -nonewline $channel $msg1$model$model_pad$msg2$msg3$msg4$msg5}
puts -nonewline $channel $msg1$msg1b$msg1c$model$model_pad$msg2$msg3$msg4 puts -nonewline $channel $msg1$msg1b$msg1c$model$model_pad$msg2$msg3$msg4
if { $opaque_len > 0 } { puts -nonewline $channel $msgop } if { $opaque_len > 0 } { puts -nonewline $channel $msgop }
@ -2436,7 +2434,7 @@ proc sendConfReplyMessage { channel node model types values opaque } {
# session number # session number
set msg3 "" set msg3 ""
if { $session != "" } { if { $session != "" } {
incr len [expr {2 + $session_len + $session_pad_len }] incr len [expr {2 + $session_len + $session_pad_len }]
set msg3 [binary format cc 0x0A $session_len] set msg3 [binary format cc 0x0A $session_len]
set msg3 $msg3$session$session_pad set msg3 $msg3$session$session_pad
} }
@ -2472,7 +2470,7 @@ proc sendEventMessage { channel type nodenum name data flags } {
set data_pad_len [pad_32bit $data_len] set data_pad_len [pad_32bit $data_len]
if { $data_len > 0 } { incr len [expr {2 + $data_len + $data_pad_len}] } if { $data_len > 0 } { incr len [expr {2 + $data_len + $data_pad_len}] }
if { $prmsg == 1 } { if { $prmsg == 1 } {
puts -nonewline ">EVENT(flags=$flags," } puts -nonewline ">EVENT(flags=$flags," }
set msg [binary format ccS 8 $flags $len ] ;# message header set msg [binary format ccS 8 $flags $len ] ;# message header
@ -2481,7 +2479,7 @@ proc sendEventMessage { channel type nodenum name data flags } {
if { $prmsg == 1 } { puts -nonewline "node=$nodenum," } if { $prmsg == 1 } { puts -nonewline "node=$nodenum," }
set msg2 [binary format c2sI {0x01 4} 0 $nodenum] set msg2 [binary format c2sI {0x01 4} 0 $nodenum]
} }
if { $prmsg == 1} { if { $prmsg == 1} {
set typestr "" set typestr ""
foreach t [array names eventtypes] { foreach t [array names eventtypes] {
if { $eventtypes($t) == $type } { set typestr "-$t"; break } if { $eventtypes($t) == $type } { set typestr "-$t"; break }
@ -2513,7 +2511,7 @@ proc sendEventMessage { channel type nodenum name data flags } {
# deploy working configuration using CORE API # deploy working configuration using CORE API
# Deploys a current working configuration. It creates all the # Deploys a current working configuration. It creates all the
# nodes and link as defined in configuration file. # nodes and link as defined in configuration file.
proc deployCfgAPI { sock } { proc deployCfgAPI { sock } {
global eid global eid
@ -2546,13 +2544,13 @@ proc deployCfgAPI { sock } {
sendSessionProperties $sock sendSessionProperties $sock
# this tells the CORE services that we are starting to send # this tells the CORE services that we are starting to send
# configuration data # configuration data
# clear any existing config # clear any existing config
sendEventMessage $sock $eventtypes(definition_state) -1 "" "" 0 sendEventMessage $sock $eventtypes(definition_state) -1 "" "" 0
# inform CORE services about emulation servers, hook scripts, canvas info, # inform CORE services about emulation servers, hook scripts, canvas info,
# and services # and services
sendEventMessage $sock $eventtypes(configuration_state) -1 "" "" 0 sendEventMessage $sock $eventtypes(configuration_state) -1 "" "" 0
sendEmulationServerInfo $sock 0 sendEmulationServerInfo $sock 0
sendSessionOptions $sock sendSessionOptions $sock
sendHooks $sock sendHooks $sock
@ -2567,7 +2565,7 @@ proc deployCfgAPI { sock } {
set type [nodeType $node] set type [nodeType $node]
set name [getNodeName $node] set name [getNodeName $node]
if { $type == "pseudo" } { continue } if { $type == "pseudo" } { continue }
statgraph inc 1 statgraph inc 1
statline "Creating node $name" statline "Creating node $name"
if { [[typemodel $node].layer] == "NETWORK" } { if { [[typemodel $node].layer] == "NETWORK" } {
@ -2611,7 +2609,7 @@ proc deployCfgAPI { sock } {
# status bar graph # status bar graph
statgraph off 0 statgraph off 0
statline "Network topology instantiated in [expr [clock seconds] - $t_start] seconds ([llength $node_list] nodes and [llength $link_list] links)." statline "Network topology instantiated in [expr [clock seconds] - $t_start] seconds ([llength $node_list] nodes and [llength $link_list] links)."
# TODO: turn on tcpdump if enabled; customPostConfigCommands; # TODO: turn on tcpdump if enabled; customPostConfigCommands;
# addons 4 deployCfgHook # addons 4 deployCfgHook
@ -2628,8 +2626,8 @@ proc deployCfgAPI { sock } {
sendTrafficScripts $sock sendTrafficScripts $sock
# tell the CORE services that we are ready to instantiate # tell the CORE services that we are ready to instantiate
sendEventMessage $sock $eventtypes(instantiation_state) -1 "" "" 0 sendEventMessage $sock $eventtypes(instantiation_state) -1 "" "" 0
set deployCfgAPI_lock 0 ;# unlock set deployCfgAPI_lock 0 ;# unlock
statline "Network topology instantiated in [expr [clock seconds] - $t_start] seconds ([llength $node_list] nodes and [llength $link_list] links)." statline "Network topology instantiated in [expr [clock seconds] - $t_start] seconds ([llength $node_list] nodes and [llength $link_list] links)."
@ -2651,7 +2649,7 @@ proc shutdownSession {} {
set plugin [lindex [getEmulPlugin "*"] 0] set plugin [lindex [getEmulPlugin "*"] 0]
set sock [pluginConnect $plugin connect true] set sock [pluginConnect $plugin connect true]
sendEventMessage $sock $eventtypes(datacollect_state) -1 "" "" 0 sendEventMessage $sock $eventtypes(datacollect_state) -1 "" "" 0
# shut down all links # shut down all links
foreach link $link_list { foreach link $link_list {
@ -2712,7 +2710,7 @@ proc sendNodeTypeInfo { sock reset } {
sendConfRequestMessage $sock -1 "all" 0x3 -1 "" sendConfRequestMessage $sock -1 "all" 0x3 -1 ""
return return
} }
# build a list of node types in use # build a list of node types in use
set typesinuse "" set typesinuse ""
foreach node $node_list { foreach node $node_list {
set type [nodeType $node] set type [nodeType $node]
@ -2974,7 +2972,7 @@ proc sendFileMessage { channel node type f sf data data_len } {
set prmsg $showAPI set prmsg $showAPI
set node_num [string range $node 1 end] set node_num [string range $node 1 end]
set f_len [string length $f] set f_len [string length $f]
set f_pad_len [pad_32bit $f_len] set f_pad_len [pad_32bit $f_len]
set f_pad [binary format x$f_pad_len] set f_pad [binary format x$f_pad_len]
@ -3013,7 +3011,7 @@ proc sendFileMessage { channel node type f sf data data_len } {
if { $prmsg == 1 } { if { $prmsg == 1 } {
puts -nonewline ">FILE(flags=$flags,$node,f=$f," puts -nonewline ">FILE(flags=$flags,$node,f=$f,"
if { $type != "" } { puts -nonewline "type=$type," } if { $type != "" } { puts -nonewline "type=$type," }
if { $sf != "" } { puts "src=$sf)" if { $sf != "" } { puts "src=$sf)"
} else { puts "data=($data_len))" } } else { puts "data=($data_len))" }
} }
@ -3077,7 +3075,7 @@ proc sendSessionMessage { channel flags num name sfile nodecount tf user } {
set user_pad_len [pad_32bit $user_len] set user_pad_len [pad_32bit $user_len]
if { $user_len > 0 } { incr len [expr { 2 + $user_len + $user_pad_len }] } if { $user_len > 0 } { incr len [expr { 2 + $user_len + $user_pad_len }] }
if { $prmsg == 1 } { if { $prmsg == 1 } {
puts -nonewline ">SESSION(flags=$flags" } puts -nonewline ">SESSION(flags=$flags" }
set msgh [binary format ccS 0x09 $flags $len ] ;# message header set msgh [binary format ccS 0x09 $flags $len ] ;# message header
@ -3089,7 +3087,7 @@ proc sendSessionMessage { channel flags num name sfile nodecount tf user } {
set msg2 "" set msg2 ""
if { $name_len > 0 } { if { $name_len > 0 } {
if { $prmsg == 1 } { puts -nonewline ",name=$name" } if { $prmsg == 1 } { puts -nonewline ",name=$name" }
# TODO: name_len > 255 # TODO: name_len > 255
set name_hdr [binary format cc 0x02 $name_len] set name_hdr [binary format cc 0x02 $name_len]
set name_pad [binary format x$name_pad_len] set name_pad [binary format x$name_pad_len]
set msg2 "$name_hdr$name$name_pad" set msg2 "$name_hdr$name$name_pad"
@ -3097,7 +3095,7 @@ proc sendSessionMessage { channel flags num name sfile nodecount tf user } {
set msg3 "" set msg3 ""
if { $sfile_len > 0 } { if { $sfile_len > 0 } {
if { $prmsg == 1 } { puts -nonewline ",file=$sfile" } if { $prmsg == 1 } { puts -nonewline ",file=$sfile" }
# TODO: sfile_len > 255 # TODO: sfile_len > 255
set sfile_hdr [binary format cc 0x03 $sfile_len] set sfile_hdr [binary format cc 0x03 $sfile_len]
set sfile_pad [binary format x$sfile_pad_len] set sfile_pad [binary format x$sfile_pad_len]
set msg3 "$sfile_hdr$sfile$sfile_pad" set msg3 "$sfile_hdr$sfile$sfile_pad"
@ -3150,11 +3148,11 @@ proc xmlFileLoadSave { cmd name } {
# inform daemon about nodes and links when saving in edit mode # inform daemon about nodes and links when saving in edit mode
if { $cmd == "save" && $oper_mode != "exec" } { if { $cmd == "save" && $oper_mode != "exec" } {
sendSessionProperties $sock sendSessionProperties $sock
# this tells the CORE services that we are starting to send # this tells the CORE services that we are starting to send
# configuration data # configuration data
# clear any existing config # clear any existing config
sendEventMessage $sock $eventtypes(definition_state) -1 "" "" 0 sendEventMessage $sock $eventtypes(definition_state) -1 "" "" 0
sendEventMessage $sock $eventtypes(configuration_state) -1 "" "" 0 sendEventMessage $sock $eventtypes(configuration_state) -1 "" "" 0
sendEmulationServerInfo $sock 0 sendEmulationServerInfo $sock 0
sendSessionOptions $sock sendSessionOptions $sock
sendHooks $sock sendHooks $sock
@ -3246,7 +3244,7 @@ proc buildStringTLV { type data len_ref } {
} }
if { $data_len > 255 } { if { $data_len > 255 } {
set hdr [binary format ccS $type 0 $data_len] set hdr [binary format ccS $type 0 $data_len]
set hdr_len 4 set hdr_len 4
} else { } else {
set hdr [binary format cc $type $data_len] set hdr [binary format cc $type $data_len]
@ -3274,7 +3272,7 @@ proc pad_32bit { len } {
proc macToString { mac_num } { proc macToString { mac_num } {
set mac_bytes "" set mac_bytes ""
# convert 64-bit integer into 12-digit hex string # convert 64-bit integer into 12-digit hex string
set mac_num 0x[format "%.12lx" $mac_num] set mac_num 0x[format "%.12lx" $mac_num]
while { $mac_num > 0 } { while { $mac_num > 0 } {
# append 8-bit hex number to list # append 8-bit hex number to list
@ -3295,7 +3293,7 @@ proc macToString { mac_num } {
set r {} set r {}
set i [llength $mac_bytes] set i [llength $mac_bytes]
while { $i > 0 } { lappend r [lindex $mac_bytes [incr i -1]] } while { $i > 0 } { lappend r [lindex $mac_bytes [incr i -1]] }
return [join $r :] return [join $r :]
} }

View file

@ -35,24 +35,24 @@
# NAME # NAME
# cfgparse.tcl -- file used for parsing the configuration # cfgparse.tcl -- file used for parsing the configuration
# FUNCTION # FUNCTION
# This module is used for parsing the configuration, i.e. reading the # This module is used for parsing the configuration, i.e. reading the
# configuration from a file or a string and writing the configuration # 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 # to a file or a string. This module also contains a function for returning
# a new ID for nodes, links and canvases. # a new ID for nodes, links and canvases.
#**** #****
#****f* nodecfg.tcl/dumpputs #****f* nodecfg.tcl/dumpputs
# NAME # NAME
# dumpputs -- puts a string to a file or a string configuration # dumpputs -- puts a string to a file or a string configuration
# SYNOPSIS # SYNOPSIS
# dumpputs $method $destination $string # dumpputs $method $destination $string
# FUNCTION # FUNCTION
# Puts a sting to the file or appends the string configuration (used for # Puts a sting to the file or appends the string configuration (used for
# undo functions), the choice depends on the value of method parameter. # undo functions), the choice depends on the value of method parameter.
# INPUTS # INPUTS
# * method -- method used. Possiable values are file (if saving the string # * method -- method used. Possiable values are file (if saving the string
# to the file) and string (if appending the string configuration) # to the file) and string (if appending the string configuration)
# * dest -- destination used. File_id for files, and string name for string # * dest -- destination used. File_id for files, and string name for string
# configuration # configuration
# * string -- the string that is inserted to a file or appended to the string # * string -- the string that is inserted to a file or appended to the string
# configuartion # configuartion
@ -73,7 +73,7 @@ proc dumpputs {method dest string} {
#****f* nodecfg.tcl/dumpCfg #****f* nodecfg.tcl/dumpCfg
# NAME # NAME
# dumpCfg -- puts the current configuraton to a file or a string # dumpCfg -- puts the current configuraton to a file or a string
# SYNOPSIS # SYNOPSIS
# dumpCfg $method $destination # dumpCfg $method $destination
# FUNCTION # FUNCTION
@ -81,7 +81,7 @@ proc dumpputs {method dest string} {
# INPUTS # INPUTS
# * method -- used method. Possiable values are file (saving current congif # * method -- used method. Possiable values are file (saving current congif
# to the file) and string (saving current config in a string) # to the file) and string (saving current config in a string)
# * dest -- destination used. File_id for files, and string name for string # * dest -- destination used. File_id for files, and string name for string
# configurations # configurations
#**** #****
@ -95,7 +95,7 @@ proc dumpCfg {method dest} {
dumpputs $method $dest "\}" dumpputs $method $dest "\}"
dumpputs $method $dest "" dumpputs $method $dest ""
} }
foreach node $node_list { foreach node $node_list {
global $node global $node
upvar 0 $node lnode upvar 0 $node lnode
@ -129,7 +129,7 @@ proc dumpCfg {method dest} {
} }
} }
dumpputs $method $dest " \}" dumpputs $method $dest " \}"
} elseif { "[lindex $element 0]" == "ipsec-config" } { } elseif { "[lindex $element 0]" == "ipsec-config" } {
dumpputs $method $dest " ipsec-config \{" dumpputs $method $dest " ipsec-config \{"
foreach line [lindex $element 1] { foreach line [lindex $element 1] {
if { $line != {} } { if { $line != {} } {
@ -228,24 +228,24 @@ proc dumpGlobalOptions { method dest } {
global mac_addr_start global mac_addr_start
dumpputs $method $dest "option global \{" dumpputs $method $dest "option global \{"
if {$showIfNames == 0} { if {$showIfNames == 0} {
dumpputs $method $dest " interface_names no" dumpputs $method $dest " interface_names no"
} else { } else {
dumpputs $method $dest " interface_names yes" } dumpputs $method $dest " interface_names yes" }
if {$showIfIPaddrs == 0} { if {$showIfIPaddrs == 0} {
dumpputs $method $dest " ip_addresses no" dumpputs $method $dest " ip_addresses no"
} else { } else {
dumpputs $method $dest " ip_addresses yes" } dumpputs $method $dest " ip_addresses yes" }
if {$showIfIPv6addrs == 0} { if {$showIfIPv6addrs == 0} {
dumpputs $method $dest " ipv6_addresses no" dumpputs $method $dest " ipv6_addresses no"
} else { } else {
dumpputs $method $dest " ipv6_addresses yes" } dumpputs $method $dest " ipv6_addresses yes" }
if {$showNodeLabels == 0} { if {$showNodeLabels == 0} {
dumpputs $method $dest " node_labels no" dumpputs $method $dest " node_labels no"
} else { } else {
dumpputs $method $dest " node_labels yes" } dumpputs $method $dest " node_labels yes" }
if {$showLinkLabels == 0} { if {$showLinkLabels == 0} {
dumpputs $method $dest " link_labels no" dumpputs $method $dest " link_labels no"
} else { } else {
dumpputs $method $dest " link_labels yes" } dumpputs $method $dest " link_labels yes" }
if {$showAPI == 0} { if {$showAPI == 0} {
@ -290,7 +290,7 @@ proc setGlobalOption { field value } {
global showIfIPaddrs showIfIPv6addrs global showIfIPaddrs showIfIPv6addrs
global showBkgImage showGrid showAnnotations global showBkgImage showGrid showAnnotations
global showAPI global showAPI
global mac_addr_start global mac_addr_start
global g_traffic_start_opt global g_traffic_start_opt
global g_view_locked global g_view_locked
@ -400,8 +400,8 @@ proc cleanupGUIState {} {
# SYNOPSIS # SYNOPSIS
# loadCfg $cfg # loadCfg $cfg
# FUNCTION # FUNCTION
# Loads the configuration written in the cfg string to a current # Loads the configuration written in the cfg string to a current
# configuration. # configuration.
# INPUTS # INPUTS
# * cfg -- string containing the new working configuration. # * cfg -- string containing the new working configuration.
#**** #****
@ -489,7 +489,7 @@ proc loadCfg { cfg } {
# consume first two list elements from line # consume first two list elements from line
set value [lindex $line 1] set value [lindex $line 1]
set line [lreplace $line 0 1] set line [lreplace $line 0 1]
if {"$class" == "node"} { if {"$class" == "node"} {
switch -exact -- $field { switch -exact -- $field {
type { type {
@ -561,7 +561,7 @@ proc loadCfg { cfg } {
} }
ipsec-config { ipsec-config {
set cfg "" set cfg ""
foreach zline [split $value { foreach zline [split $value {
}] { }] {
if { [string index "$zline" 0] == " " } { if { [string index "$zline" 0] == " " } {
@ -600,7 +600,8 @@ proc loadCfg { cfg } {
custom-pre-config-commands { custom-pre-config-commands {
# Boeing - custom pre config commands # Boeing - custom pre config commands
set cfg "" set cfg ""
foreach zline [split $value { }] { foreach zline [split $value {
}] {
if { [string index "$zline" 0] == " " } { if { [string index "$zline" 0] == " " } {
set zline [string replace "$zline" 0 0] set zline [string replace "$zline" 0 0]
} }
@ -612,7 +613,8 @@ proc loadCfg { cfg } {
custom-post-config-commands { custom-post-config-commands {
# Boeing - custom post config commands # Boeing - custom post config commands
set cfg "" set cfg ""
foreach zline [split $value { }] { foreach zline [split $value {
}] {
if { [string index "$zline" 0] == " " } { if { [string index "$zline" 0] == " " } {
set zline [string replace "$zline" 0 0] set zline [string replace "$zline" 0 0]
} }
@ -628,7 +630,8 @@ proc loadCfg { cfg } {
ine-config { ine-config {
# Boeing - INE # Boeing - INE
set cfg "" set cfg ""
foreach zline [split $value { }] { foreach zline [split $value {
}] {
if { [string index "$zline" 0] == " " } { if { [string index "$zline" 0] == " " } {
set zline [string replace "$zline" 0 0] set zline [string replace "$zline" 0 0]
} }
@ -682,7 +685,7 @@ proc loadCfg { cfg } {
switch -exact -- $field { switch -exact -- $field {
name { name {
lappend $object "name $value" lappend $object "name $value"
} }
height { height {
lappend $object "height $value" lappend $object "height $value"
} }
@ -695,10 +698,10 @@ proc loadCfg { cfg } {
y { y {
lappend $object "y $value" lappend $object "y $value"
} }
color { color {
lappend $object "color $value" lappend $object "color $value"
} }
} }
} elseif {"$class" == "link"} { } elseif {"$class" == "link"} {
switch -exact -- $field { switch -exact -- $field {
nodes { nodes {
@ -863,20 +866,20 @@ proc loadCfg { cfg } {
#****f* nodecfg.tcl/newObjectId #****f* nodecfg.tcl/newObjectId
# NAME # NAME
# newObjectId -- new object Id # newObjectId -- new object Id
# SYNOPSIS # SYNOPSIS
# set obj_id [newObjectId $type] # set obj_id [newObjectId $type]
# FUNCTION # FUNCTION
# Returns the Id for a new object of the defined type. Supported types # 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 # 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 # first letter of the given type and $number is the first available number to
# that can be used for id. # that can be used for id.
# INPUTS # INPUTS
# * type -- the type of the new object. Can be node, link or canvas. # * type -- the type of the new object. Can be node, link or canvas.
# RESULT # RESULT
# * obj_id -- object Id in the form $mark$number. $mark is the # * 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 # first letter of the given type and $number is the first available number to
# that can be used for id. # that can be used for id.
#**** #****
proc newObjectId { type } { proc newObjectId { type } {
@ -950,7 +953,7 @@ proc loadServersConf { } {
global CONFDIR exec_servers DEFAULT_API_PORT global CONFDIR exec_servers DEFAULT_API_PORT
set confname "$CONFDIR/servers.conf" set confname "$CONFDIR/servers.conf"
if { [catch { set f [open "$confname" r] } ] } { if { [catch { set f [open "$confname" r] } ] } {
puts "Creating a default $confname" puts "Creating a default $confname"
if { [catch { set f [open "$confname" w+] } ] } { if { [catch { set f [open "$confname" w+] } ] } {
puts "***Warning: could not create a default $confname file." puts "***Warning: could not create a default $confname file."
return return
@ -1035,7 +1038,7 @@ proc popupPrefs {} {
-command "addFileToMrulist \"\"" -command "addFileToMrulist \"\""
pack $wi.dirs.mru.label $wi.dirs.mru.num $wi.dirs.mru.clear -side left 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.mru -side top -anchor w -padx 4 -pady 4
pack $wi.dirs -side top -fill x pack $wi.dirs -side top -fill x
# #
@ -1049,7 +1052,7 @@ proc popupPrefs {} {
-variable g_prefs(gui_save_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.savepos $wi.win.win.savesiz -side left -anchor w -padx 4
pack $wi.win.win -side top -anchor w -padx 4 -pady 4 pack $wi.win.win -side top -anchor w -padx 4 -pady 4
frame $wi.win.a frame $wi.win.a
checkbutton $wi.win.a.snaptogrid -text "snap to grid" \ checkbutton $wi.win.a.snaptogrid -text "snap to grid" \
-variable g_prefs(gui_snap_grid) -variable g_prefs(gui_snap_grid)
@ -1123,9 +1126,8 @@ proc initDefaultPrefs {} {
# variable expansions must be done here # variable expansions must be done here
array set g_prefs [list default_conf_path "$CONFDIR/configs"] array set g_prefs [list default_conf_path "$CONFDIR/configs"]
array set g_prefs [list gui_canvas_refpt "$DEFAULT_REFPT"] array set g_prefs [list gui_canvas_refpt "$DEFAULT_REFPT"]
if { $tcl_platform(os) == "FreeBSD" } { set shell "/usr/local/bin/bash" set shell "bash"
} else { set shell "bash" } array set g_prefs [list shell $shell]
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_text_editor [get_text_editor true]]
array set g_prefs [list gui_term_prog [get_term_prog true]] array set g_prefs [list gui_term_prog [get_term_prog true]]
setDefaultAddrs ipv4 setDefaultAddrs ipv4

View file

@ -86,11 +86,7 @@ node n2 {
HN=`hostname` HN=`hostname`
SCRIPTDIR=$SESSION_DIR SCRIPTDIR=$SESSION_DIR
LOGDIR=/var/log LOGDIR=/var/log
if [ `uname` = "FreeBSD" ]; then
SCRIPTDIR=/tmp/e0_$HN
LOGDIR=$SCRIPTDIR
fi
cd $SCRIPTDIR cd $SCRIPTDIR
( (
cat << 'EOF' cat << 'EOF'

View file

@ -34,7 +34,7 @@
#****h* imunes/editor.tcl #****h* imunes/editor.tcl
# NAME # NAME
# editor.tcl -- file used for defining functions that can be used in # editor.tcl -- file used for defining functions that can be used in
# edit mode as well as all the functions which change the appearance # edit mode as well as all the functions which change the appearance
# of the imunes GUI. # of the imunes GUI.
# FUNCTION # FUNCTION
# This module is used for defining all possible actions in imunes # This module is used for defining all possible actions in imunes
@ -71,8 +71,8 @@ proc animateCursor {} {
# split links and links connecting nodes on different canvases. # split links and links connecting nodes on different canvases.
# INPUTS # INPUTS
# * link_id -- the link id # * link_id -- the link id
# * atomic -- defines if the remove was atomic action or a part # * atomic -- defines if the remove was atomic action or a part
# of a composed, non-atomic action (relevant for updating log # of a composed, non-atomic action (relevant for updating log
# for undo). # for undo).
#**** #****
@ -137,7 +137,7 @@ proc removeGUINode { node } {
# SYNOPSIS # SYNOPSIS
# updateUndoLog # updateUndoLog
# FUNCTION # FUNCTION
# Updates the undo log. Writes the current configuration to the # Updates the undo log. Writes the current configuration to the
# undolog array and updates the undolevel variable. # undolog array and updates the undolevel variable.
#**** #****
@ -161,7 +161,7 @@ proc updateUndoLog {} {
# NAME # NAME
# undo -- undo function # undo -- undo function
# SYNOPSIS # SYNOPSIS
# undo # undo
# FUNCTION # FUNCTION
# Undo the change. Reads the undolog and updates the current # Undo the change. Reads the undolog and updates the current
# configuration. Reduces the value of undolevel. # configuration. Reduces the value of undolevel.
@ -185,10 +185,10 @@ proc undo {} {
# SYNOPSIS # SYNOPSIS
# redo # redo
# FUNCTION # FUNCTION
# Redo the change if possible (redolevel is greater than # Redo the change if possible (redolevel is greater than
# undolevel). Reads the configuration from undolog and # undolevel). Reads the configuration from undolog and
# updates the current configuration. Increases the value # updates the current configuration. Increases the value
# of undolevel. # of undolevel.
#**** #****
proc redo {} { proc redo {} {
@ -244,7 +244,7 @@ proc redrawAll {} {
"-$border -$border [expr {$e_sizex + $border}] \ "-$border -$border [expr {$e_sizex + $border}] \
[expr {$e_sizey + $border}]" [expr {$e_sizey + $border}]"
saveRestoreWlanLinks .c save saveRestoreWlanLinks .c save
.c delete all .c delete all
set background [.c create rectangle 0 0 $e_sizex $e_sizey \ set background [.c create rectangle 0 0 $e_sizex $e_sizey \
@ -264,7 +264,7 @@ proc redrawAll {} {
if { [getNodeCanvas $obj] == $curcanvas } { if { [getNodeCanvas $obj] == $curcanvas } {
drawAnnotation $obj drawAnnotation $obj
} }
} }
} }
# Grid # Grid
@ -303,7 +303,7 @@ proc redrawAll {} {
} }
} }
redrawAllThruplots redrawAllThruplots
foreach link $link_list { foreach link $link_list {
set nodes [linkPeers $link] set nodes [linkPeers $link]
if { [getNodeCanvas [lindex $nodes 0]] != $curcanvas || if { [getNodeCanvas [lindex $nodes 0]] != $curcanvas ||
@ -330,7 +330,7 @@ proc redrawAll {} {
# Draws the specified node. Draws node's image (router pc # Draws the specified node. Draws node's image (router pc
# host lanswitch rj45 hub pseudo) and label. # host lanswitch rj45 hub pseudo) and label.
# The visibility of the label depends on the showNodeLabels # The visibility of the label depends on the showNodeLabels
# variable for all types of nodes and on invisible variable # variable for all types of nodes and on invisible variable
# for pseudo nodes. # for pseudo nodes.
# INPUTS # INPUTS
# * node_id -- node id # * node_id -- node id
@ -342,7 +342,7 @@ proc drawNode { c node } {
global curcanvas zoom global curcanvas zoom
global wlan global wlan
if { $c == "" } { set c .c } ;# default canvas if { $c == "" } { set c .c } ;# default canvas
set type [nodeType $node] set type [nodeType $node]
set coords [getNodeCoords $node] set coords [getNodeCoords $node]
set x [expr {[lindex $coords 0] * $zoom}] set x [expr {[lindex $coords 0] * $zoom}]
@ -361,7 +361,7 @@ proc drawNode { c node } {
if { $tmp != "" } { set cimg $tmp } if { $tmp != "" } { set cimg $tmp }
if { $cimg != "" } { if { $cimg != "" } {
# name of global variable storing the image is the filename without path # name of global variable storing the image is the filename without path
set img [file tail $cimg] set img [file tail $cimg]
# create the variable if the image hasn't been loaded before # create the variable if the image hasn't been loaded before
global [set img] global [set img]
if { ![info exists $img] } { if { ![info exists $img] } {
@ -433,9 +433,9 @@ proc drawNode { c node } {
# SYNOPSIS # SYNOPSIS
# drawLink link_id # drawLink link_id
# FUNCTION # FUNCTION
# Draws the specified link. An arrow is displayed for links # Draws the specified link. An arrow is displayed for links
# connected to pseudo nodes. If the variable invisible # connected to pseudo nodes. If the variable invisible
# is specified link connecting a pseudo node stays hidden. # is specified link connecting a pseudo node stays hidden.
# INPUTS # INPUTS
# * link_id -- link id # * link_id -- link id
#**** #****
@ -486,7 +486,7 @@ proc drawLink { link } {
} }
foreach n [list $lnode1 $lnode2] { foreach n [list $lnode1 $lnode2] {
if { [getNodeHidden $n] } { if { [getNodeHidden $n] } {
hideNode $n hideNode $n
statline "Hidden node(s) exist." statline "Hidden node(s) exist."
} }
} }
@ -535,7 +535,7 @@ proc drawWlanLink { node1 node2 wlan } {
# set ifcName [chooseIfName $lnode1 $lnode2] # set ifcName [chooseIfName $lnode1 $lnode2]
# FUNCTION # FUNCTION
# Choose intreface name. The name can be: # Choose intreface name. The name can be:
# * eth -- for interface connecting pc, host and router # * eth -- for interface connecting pc, host and router
# * e -- for interface connecting hub and lanswitch # * e -- for interface connecting hub and lanswitch
# INPUTS # INPUTS
# * link_id -- link id # * link_id -- link id
@ -564,7 +564,7 @@ proc chooseIfName { lnode1 lnode2 } {
return eth return eth
} }
rj45 { rj45 {
return return
} }
tunnel { tunnel {
return e return e
@ -589,8 +589,8 @@ proc chooseIfName { lnode1 lnode2 } {
# SYNOPSIS # SYNOPSIS
# set l2peers [listLANNodes $l2node $l2peers] # set l2peers [listLANNodes $l2node $l2peers]
# FUNCTION # FUNCTION
# Recursive function for finding all link layer nodes that are # Recursive function for finding all link layer nodes that are
# connected to node l2node. Returns the list of all link layer # connected to node l2node. Returns the list of all link layer
# nodes that are on the same LAN as l2node. # nodes that are on the same LAN as l2node.
# INPUTS # INPUTS
# * l2node -- node id of a link layer node # * l2node -- node id of a link layer node
@ -622,7 +622,7 @@ proc listLANnodes { l2node l2peers } {
# FUNCTION # FUNCTION
# Calculates dx and dy variables of the calling function. # Calculates dx and dy variables of the calling function.
# INPUTS # INPUTS
# * lnode -- node id of a node whose dx and dy coordinates are # * lnode -- node id of a node whose dx and dy coordinates are
# calculated # calculated
#**** #****
@ -680,8 +680,8 @@ proc calcDxDy { lnode } {
# address and IPv6 address. # address and IPv6 address.
# INPUTS # INPUTS
# * lnode1 -- node id of a node where the interface resides # * lnode1 -- node id of a node where the interface resides
# * lnode2 -- node id of the node that is connected by this # * lnode2 -- node id of the node that is connected by this
# interface. # interface.
#**** #****
proc updateIfcLabel { lnode1 lnode2 } { proc updateIfcLabel { lnode1 lnode2 } {
global showIfNames showIfIPaddrs showIfIPv6addrs global showIfNames showIfIPaddrs showIfIPv6addrs
@ -715,7 +715,7 @@ proc updateIfcLabel { lnode1 lnode2 } {
.c itemconfigure "interface && $lnode1 && $link" \ .c itemconfigure "interface && $lnode1 && $link" \
-text "$labelstr" -text "$labelstr"
# Boeing: hide ifc label on wlans # Boeing: hide ifc label on wlans
if { [nodeType $lnode1] == "wlan" } { if { [nodeType $lnode1] == "wlan" } {
.c itemconfigure "interface && $lnode1 && $link" -state hidden .c itemconfigure "interface && $lnode1 && $link" -state hidden
} }
} }
@ -876,11 +876,11 @@ proc redrawWlanLink { link } {
#****f* editor.tcl/splitGUILink #****f* editor.tcl/splitGUILink
# NAME # NAME
# splitGUILink -- splits a links # splitGUILink -- splits a links
# SYNOPSIS # SYNOPSIS
# splitGUILink $link # splitGUILink $link
# FUNCTION # FUNCTION
# Splits the link and draws new links and new pseudo nodes # Splits the link and draws new links and new pseudo nodes
# on the canvas. # on the canvas.
# INPUTS # INPUTS
# * link -- link id # * link -- link id
@ -925,7 +925,7 @@ proc splitGUILink { link } {
#****f* editor.tcl/selectNode #****f* editor.tcl/selectNode
# NAME # NAME
# selectNode -- select node # selectNode -- select node
# SYNOPSIS # SYNOPSIS
# selectNode $c $obj # selectNode $c $obj
# FUNCTION # FUNCTION
@ -1019,11 +1019,11 @@ proc selectAdjacent {} {
#****f* editor.tcl/button3link #****f* editor.tcl/button3link
# NAME # NAME
# button3link # button3link
# SYNOPSIS # SYNOPSIS
# button3link $c $x $y # button3link $c $x $y
# FUNCTION # FUNCTION
# This procedure is called when a right mouse button is # This procedure is called when a right mouse button is
# clicked on the canvas. If there is a link on the place of # clicked on the canvas. If there is a link on the place of
# mouse click this procedure creates and configures a popup # mouse click this procedure creates and configures a popup
# menu. The options in the menu are: # menu. The options in the menu are:
@ -1099,7 +1099,7 @@ proc button3link { c x y } {
#****f* editor.tcl/movetoCanvas #****f* editor.tcl/movetoCanvas
# NAME # NAME
# movetoCanvas -- move to canvas # movetoCanvas -- move to canvas
# SYNOPSIS # SYNOPSIS
# movetoCanvas $canvas # movetoCanvas $canvas
# FUNCTION # FUNCTION
@ -1176,7 +1176,7 @@ proc mergeGUINode { node } {
# SYNOPSIS # SYNOPSIS
# button3node $c $x $y # button3node $c $x $y
# FUNCTION # FUNCTION
# This procedure is called when a right mouse button is # This procedure is called when a right mouse button is
# clicked on the canvas. Also called when double-clicking # clicked on the canvas. Also called when double-clicking
# on a node during runtime. # on a node during runtime.
# If there is a node on the place of # If there is a node on the place of
@ -1190,18 +1190,18 @@ proc mergeGUINode { node } {
# that have mirror nodes on the same canvas (Pseudo nodes # that have mirror nodes on the same canvas (Pseudo nodes
# created by splitting a link). # created by splitting a link).
# * Delete -- delete the node # * Delete -- delete the node
# * Shell window -- specifies the shell window to open in # * Shell window -- specifies the shell window to open in
# exec mode. This option is available only to nodes on a # exec mode. This option is available only to nodes on a
# network layer # network layer
# * Ethereal -- opens a Ethereal program for the specified # * Ethereal -- opens a Ethereal program for the specified
# node and the specified interface. This option is available # node and the specified interface. This option is available
# only for network layer nodes in exec mode. # only for network layer nodes in exec mode.
# INPUTS # INPUTS
# * c -- tk canvas # * c -- tk canvas
# * x -- x coordinate for popup menu # * x -- x coordinate for popup menu
# * y -- y coordinate for popup menu # * y -- y coordinate for popup menu
#**** #****
#old proc button3node { c x y } #old proc button3node { c x y }
#Boeing #Boeing
proc button3node { c x y button } { proc button3node { c x y button } {
global oper_mode env eid canvas_list node_list curcanvas systype g_prefs global oper_mode env eid canvas_list node_list curcanvas systype g_prefs
@ -1242,7 +1242,7 @@ proc button3node { c x y button } {
if { $button == "shift" } { ;# normal bash shell if { $button == "shift" } { ;# normal bash shell
spawnShell $node $shell spawnShell $node $shell
} else { ;# right-click vtysh shell } else { ;# right-click vtysh shell
set cmd [[typemodel $node].shellcmd $node] set cmd [[typemodel $node].shellcmd $node]
if { $cmd != "/bin/sh" && $cmd != "" } { spawnShell $node $cmd } if { $cmd != "/bin/sh" && $cmd != "" } { spawnShell $node $cmd }
} }
return ;# open shell, don't post a menu return ;# open shell, don't post a menu
@ -1437,7 +1437,7 @@ proc button3node { c x y button } {
addInterfaceCommand $node .button3menu "Wireshark" "wireshark -k -i" \ addInterfaceCommand $node .button3menu "Wireshark" "wireshark -k -i" \
$execstate 0 $execstate 0
# wireshark on host veth pair -- need veth pair name # wireshark on host veth pair -- need veth pair name
#wireshark -k -i #wireshark -k -i
if { [lindex $systype 0] == "Linux" } { if { [lindex $systype 0] == "Linux" } {
set name [getNodeName $node] set name [getNodeName $node]
.button3menu add command -label "View log..." -state $execstate \ .button3menu add command -label "View log..." -state $execstate \
@ -1464,7 +1464,7 @@ proc button3node { c x y button } {
# This procedure spawns a new shell for a specified node. # This procedure spawns a new shell for a specified node.
# The shell is specified in cmd parameter. # The shell is specified in cmd parameter.
# INPUTS # INPUTS
# * node -- node id of the node for which the shell # * node -- node id of the node for which the shell
# is spawned. # is spawned.
# * cmd -- the path to the shell. # * cmd -- the path to the shell.
#**** #****
@ -1527,9 +1527,9 @@ proc raiseAll {c} {
# SYNOPSIS # SYNOPSIS
# button1 $c $x $y $button # button1 $c $x $y $button
# FUNCTION # FUNCTION
# This procedure is called when a left mouse button is # This procedure is called when a left mouse button is
# clicked on the canvas. This procedure selects a new # clicked on the canvas. This procedure selects a new
# node or creates a new node, depending on the selected # node or creates a new node, depending on the selected
# tool. # tool.
# INPUTS # INPUTS
# * c -- tk canvas # * c -- tk canvas
@ -1563,7 +1563,7 @@ proc button1 { c x y button } {
set curobj [$c find withtag current] set curobj [$c find withtag current]
set curtype [lindex [$c gettags current] 0] set curtype [lindex [$c gettags current] 0]
if { $curtype == "node" || \ if { $curtype == "node" || \
$curtype == "oval" || $curtype == "rectangle" || $curtype == "text" \ $curtype == "oval" || $curtype == "rectangle" || $curtype == "text" \
|| ( $curtype == "nodelabel" && \ || ( $curtype == "nodelabel" && \
@ -1613,7 +1613,7 @@ proc button1 { c x y button } {
if { $g_view_locked == 1 } { return } if { $g_view_locked == 1 } { return }
if { $activetoolp == "routers" } { if { $activetoolp == "routers" } {
if {$activetool != "OVS"} { if {$activetool != "OVS"} {
set node [newNode router] set node [newNode router]
} else { } else {
set node [newNode OVS]} set node [newNode OVS]}
setNodeModel $node $activetool setNodeModel $node $activetool
@ -1666,7 +1666,7 @@ proc button1 { c x y button } {
set newlink [$c create line $lastX $lastY $x $y \ set newlink [$c create line $lastX $lastY $x $y \
-fill $defLinkColor -width $defLinkWidth \ -fill $defLinkColor -width $defLinkWidth \
-tags "link"] -tags "link"]
# twonode tool support # twonode tool support
} elseif {$g_twoNodeSelect != "" && $curtype == "node"} { } elseif {$g_twoNodeSelect != "" && $curtype == "node"} {
set curnode [lindex [$c gettags $curobj] 1] set curnode [lindex [$c gettags $curobj] 1]
selectTwoNode $curnode selectTwoNode $curnode
@ -1683,14 +1683,14 @@ proc setResizeMode { c x y } {
set isThruplot false set isThruplot false
set type1 notset set type1 notset
if {$c == ".c"} { if {$c == ".c"} {
set t1 [$c gettags current] set t1 [$c gettags current]
set o1 [lindex $t1 1] set o1 [lindex $t1 1]
set type1 [nodeType $o1] set type1 [nodeType $o1]
} else { } else {
set o1 $c set o1 $c
set c .c set c .c
set isThruplot true set isThruplot true
} }
#DYL #DYL
#puts "RESIZE NODETYPE = $type1" #puts "RESIZE NODETYPE = $type1"
@ -1743,11 +1743,11 @@ proc setResizeMode { c x y } {
# NAME # NAME
# button1-motion # button1-motion
# SYNOPSIS # SYNOPSIS
# button1-motion $c $x $y # button1-motion $c $x $y
# FUNCTION # FUNCTION
# This procedure is called when a left mouse button is # This procedure is called when a left mouse button is
# pressed and the mouse is moved around the canvas. # pressed and the mouse is moved around the canvas.
# This procedure creates new select box, moves the # This procedure creates new select box, moves the
# selected nodes or draws a new link. # selected nodes or draws a new link.
# INPUTS # INPUTS
# * c -- tk canvas # * c -- tk canvas
@ -1767,8 +1767,8 @@ proc button1-motion { c x y } {
if {$thruPlotDragStart == "dragging"} { if {$thruPlotDragStart == "dragging"} {
#puts "active tool is $activetool" #puts "active tool is $activetool"
thruPlotDrag $c $thruPlotCur $x $y null true thruPlotDrag $c $thruPlotCur $x $y null true
return return
} }
# fix occasional error # fix occasional error
@ -1800,7 +1800,7 @@ proc button1-motion { c x y } {
set dx [expr {$x-$lastX} ] set dx [expr {$x-$lastX} ]
set dy [expr {$y-$lastY} ] set dy [expr {$y-$lastY} ]
# this provides smoother drawing # this provides smoother drawing
if { $dx > $markersize || $dy > $markersize } { if { $dx > $markersize || $dy > $markersize } {
set mark [$c create line $lastX $lastY $x $y \ set mark [$c create line $lastX $lastY $x $y \
-width $markersize -fill $markercolor -tags "marker"] -width $markersize -fill $markercolor -tags "marker"]
$c raise $mark \ $c raise $mark \
@ -1886,7 +1886,7 @@ proc button1-motion { c x y } {
} }
# resizing an annotation # resizing an annotation
} elseif { $curtype == "selectmark" } { } elseif { $curtype == "selectmark" } {
foreach o [$c find withtag "selected"] { foreach o [$c find withtag "selected"] {
set node [lindex [$c gettags $o] 1] set node [lindex [$c gettags $o] 1]
set tagovi [$c gettags $o] set tagovi [$c gettags $o]
set koord [getNodeCoords $node] set koord [getNodeCoords $node]
@ -1992,12 +1992,12 @@ proc button1-motion { c x y } {
#****f* editor.tcl/pseudo.layer #****f* editor.tcl/pseudo.layer
# NAME # NAME
# pseudo.layer # pseudo.layer
# SYNOPSIS # SYNOPSIS
# set layer [pseudo.layer] # set layer [pseudo.layer]
# FUNCTION # FUNCTION
# Returns the layer on which the pseudo node operates # Returns the layer on which the pseudo node operates
# i.e. returns no layer. # i.e. returns no layer.
# RESULT # RESULT
# * layer -- returns an empty string # * layer -- returns an empty string
#**** #****
@ -2011,8 +2011,8 @@ proc pseudo.layer {} {
# SYNOPSIS # SYNOPSIS
# newGUILink $lnode1 $lnode2 # newGUILink $lnode1 $lnode2
# FUNCTION # FUNCTION
# This procedure is called to create a new link between # This procedure is called to create a new link between
# nodes lnode1 and lnode2. Nodes can be on the same canvas # nodes lnode1 and lnode2. Nodes can be on the same canvas
# or on different canvases. The result of this function # or on different canvases. The result of this function
# is directly visible in GUI. # is directly visible in GUI.
# INPUTS # INPUTS
@ -2052,10 +2052,10 @@ proc newGUILink { lnode1 lnode2 } {
# NAME # NAME
# button1-release # button1-release
# SYNOPSIS # SYNOPSIS
# button1-release $c $x $y # button1-release $c $x $y
# FUNCTION # FUNCTION
# This procedure is called when a left mouse button is # This procedure is called when a left mouse button is
# released. # released.
# The result of this function depends on the actions # The result of this function depends on the actions
# during the button1-motion procedure. # during the button1-motion procedure.
# INPUTS # INPUTS
@ -2202,7 +2202,7 @@ proc button1-release { c x y } {
nodeEnter $c nodeEnter $c
# $changed!=1 # $changed!=1
} elseif {$activetool == "select" } { } elseif {$activetool == "select" } {
if {$selectbox == ""} { if {$selectbox == ""} {
set x1 $x set x1 $x
set y1 $y set y1 $y
@ -2243,10 +2243,10 @@ proc button1-release { c x y } {
} else { } else {
# select tool resizing an object by dragging its handles # select tool resizing an object by dragging its handles
# DYL bugfix. if x,y does not change, do not resize! # DYL bugfix. if x,y does not change, do not resize!
# fixes a bug where the object dissappears # fixes a bug where the object dissappears
if { $x != $x1 || $y != $y1 } { if { $x != $x1 || $y != $y1 } {
setNodeCoords $resizeobj "$x $y $x1 $y1" setNodeCoords $resizeobj "$x $y $x1 $y1"
} }
set redrawNeeded 1 set redrawNeeded 1
set resizemode false set resizemode false
} }
@ -2269,11 +2269,11 @@ proc button1-release { c x y } {
# SYNOPSIS # SYNOPSIS
# nodeEnter $c # nodeEnter $c
# FUNCTION # FUNCTION
# This procedure prints the node id, node name and # This procedure prints the node id, node name and
# node model (if exists), as well as all the interfaces # node model (if exists), as well as all the interfaces
# of the node in the status line. # of the node in the status line.
# Information is presented for the node above which is # Information is presented for the node above which is
# the mouse pointer. # the mouse pointer.
# INPUTS # INPUTS
# * c -- tk canvas # * c -- tk canvas
#**** #****
@ -2314,7 +2314,7 @@ proc nodeEnter { c } {
# This procedure prints the link id, link bandwidth # This procedure prints the link id, link bandwidth
# and link delay in the status line. # and link delay in the status line.
# Information is presented for the link above which is # Information is presented for the link above which is
# the mouse pointer. # the mouse pointer.
# INPUTS # INPUTS
# * c -- tk canvas # * c -- tk canvas
#**** #****
@ -2351,13 +2351,13 @@ proc anyLeave {c} {
} }
#****f* editor.tcl/checkIntRange #****f* editor.tcl/checkIntRange
# NAME # NAME
# checkIntRange -- check integer range # checkIntRange -- check integer range
# SYNOPSIS # SYNOPSIS
# set check [checkIntRange $str $low $high] # set check [checkIntRange $str $low $high]
# FUNCTION # FUNCTION
# This procedure checks the input string to see if it is # This procedure checks the input string to see if it is
# an integer between the low and high value. # an integer between the low and high value.
# INPUTS # INPUTS
# str -- string to check # str -- string to check
@ -2407,14 +2407,14 @@ proc checkHostname { str } {
} }
#****f* editor.tcl/focusAndFlash #****f* editor.tcl/focusAndFlash
# NAME # NAME
# focusAndFlash -- focus and flash # focusAndFlash -- focus and flash
# SYNOPSIS # SYNOPSIS
# focusAndFlash $W $count # focusAndFlash $W $count
# FUNCTION # FUNCTION
# This procedure sets the focus on the bad entry field # This procedure sets the focus on the bad entry field
# and on this filed it provides an effect of flashing # and on this filed it provides an effect of flashing
# for approximately 1 second. # for approximately 1 second.
# INPUTS # INPUTS
# * W -- textbox field that caused the bed entry # * W -- textbox field that caused the bed entry
@ -2454,7 +2454,7 @@ proc focusAndFlash {W {count 9}} {
# SYNOPSIS # SYNOPSIS
# popupConfigDialog $c # popupConfigDialog $c
# FUNCTION # FUNCTION
# Dynamically creates a popup dialog box for configuring # Dynamically creates a popup dialog box for configuring
# links or nodes in IMUNES. # links or nodes in IMUNES.
# INPUTS # INPUTS
# * c -- canvas id # * c -- canvas id
@ -2540,10 +2540,10 @@ proc popupConfigDialog { c } {
$wi.ftop.name insert 0 [getNodeName $target] $wi.ftop.name insert 0 [getNodeName $target]
set img [getNodeImage $target] set img [getNodeImage $target]
ttk::button $wi.ftop.img -image $img -command "popupCustomImage $target" ttk::button $wi.ftop.img -image $img -command "popupCustomImage $target"
if { $type == "rj45" } { if { $type == "rj45" } {
rj45ifclist $wi $target 0 rj45ifclist $wi $target 0
} }
# execution server # execution server
global exec_servers node_location global exec_servers node_location
set node_location [getNodeLocation $target] set node_location [getNodeLocation $target]
@ -2556,7 +2556,7 @@ proc popupConfigDialog { c } {
# end Boeing # end Boeing
pack $wi.ftop -side top pack $wi.ftop -side top
if { $type == "router" || $type == "OVS"} { if { $type == "router" || $type == "OVS"} {
ttk::frame $wi.model -borderwidth 4 ttk::frame $wi.model -borderwidth 4
ttk::label $wi.model.label -text "Type:" ttk::label $wi.model.label -text "Type:"
set runstate "disabled" set runstate "disabled"
@ -2618,7 +2618,7 @@ proc popupConfigDialog { c } {
global conntype global conntype
set conntype [netconfFetchSection $target "tunnel-type"] set conntype [netconfFetchSection $target "tunnel-type"]
if { $conntype == "" } { set conntype "UDP" } if { $conntype == "" } { set conntype "UDP" }
# TODO: clean this up # TODO: clean this up
ttk::frame $wi.linfo ttk::frame $wi.linfo
@ -2804,7 +2804,7 @@ proc popupConfigDialog { c } {
ttk::frame $wi.unilabel -borderwidth 4 ttk::frame $wi.unilabel -borderwidth 4
ttk::label $wi.unilabel.updown -text "Symmetric link effects:" ttk::label $wi.unilabel.updown -text "Symmetric link effects:"
pack $wi.unilabel.updown -side left -anchor w pack $wi.unilabel.updown -side left -anchor w
pack $wi.unilabel -side top -anchor w pack $wi.unilabel -side top -anchor w
ttk::frame $wi.bandwidth -borderwidth 4 ttk::frame $wi.bandwidth -borderwidth 4
ttk::label $wi.bandwidth.label -anchor e -text "Bandwidth (bps):" ttk::label $wi.bandwidth.label -anchor e -text "Bandwidth (bps):"
@ -2932,11 +2932,11 @@ proc popupConfigDialog { c } {
"popupConfigApply $wi $object_type $target 0" "popupConfigApply $wi $object_type $target 0"
focus $wi.butt.apply focus $wi.butt.apply
# Boeing: remove range circles upon cancel # Boeing: remove range circles upon cancel
if {$type == "wlan"} { if {$type == "wlan"} {
set cancelcmd "set badentry -1 ; destroy $wi;" set cancelcmd "set badentry -1 ; destroy $wi;"
set cancelcmd "$cancelcmd updateRangeCircles $target 0" set cancelcmd "$cancelcmd updateRangeCircles $target 0"
} else { } else {
set cancelcmd "set badentry -1 ; destroy $wi" set cancelcmd "set badentry -1 ; destroy $wi"
} }
ttk::button $wi.butt.cancel -text "Cancel" -command $cancelcmd ttk::button $wi.butt.cancel -text "Cancel" -command $cancelcmd
#end Boeing #end Boeing
@ -3072,18 +3072,18 @@ proc macEntryHelper { wi ifc } {
# SYNOPSIS # SYNOPSIS
# popupConfigApply $w $object_type $target $phase # popupConfigApply $w $object_type $target $phase
# FUNCTION # FUNCTION
# This procedure is called when the button apply is pressed in # This procedure is called when the button apply is pressed in
# popup configuration dialog box. It reads different # popup configuration dialog box. It reads different
# configuration parameters depending on the object_type. # configuration parameters depending on the object_type.
# INPUTS # INPUTS
# * w -- widget # * w -- widget
# * object_type -- describes the object type that is currently # * object_type -- describes the object type that is currently
# configured. It can be either link or node. # configured. It can be either link or node.
# * target -- node id of the configured node or link id of the # * target -- node id of the configured node or link id of the
# configured link # configured link
# * phase -- This procedure is invoked in two diffenet phases # * phase -- This procedure is invoked in two diffenet phases
# to enable validation of the entry that was the last made. # to enable validation of the entry that was the last made.
# When calling this function always use the phase parameter # When calling this function always use the phase parameter
# set to 0. # set to 0.
#**** #****
proc popupConfigApply { wi object_type target phase } { proc popupConfigApply { wi object_type target phase } {
@ -3131,12 +3131,12 @@ proc popupConfigApply { wi object_type target phase } {
# Boeing - added wlan, remote, tunnel, ktunnel items # Boeing - added wlan, remote, tunnel, ktunnel items
if { $type == "wlan" } { if { $type == "wlan" } {
wlanConfigDialogHelper $wi $target 1 wlanConfigDialogHelper $wi $target 1
} elseif { $type == "tunnel" } { } elseif { $type == "tunnel" } {
# #
# apply tunnel items # apply tunnel items
# #
set ipaddr "$name/24" ;# tunnel name == IP address of peer set ipaddr "$name/24" ;# tunnel name == IP address of peer
set oldipaddr [getIfcIPv4addr $target e0] set oldipaddr [getIfcIPv4addr $target e0]
if { $ipaddr != $oldipaddr } { if { $ipaddr != $oldipaddr } {
setIfcIPv4addr $target e0 $ipaddr setIfcIPv4addr $target e0 $ipaddr
@ -3176,7 +3176,7 @@ proc popupConfigApply { wi object_type target phase } {
if { $oldlocal != $local } { if { $oldlocal != $local } {
netconfInsertSection $target [list "local-hook" $local] netconfInsertSection $target [list "local-hook" $local]
} }
# Boeing changing to interface name for RJ45 # Boeing changing to interface name for RJ45
# } elseif { $type == "rj45" } { # } elseif { $type == "rj45" } {
# # # #
# # apply rj45 items # # apply rj45 items
@ -3240,7 +3240,7 @@ proc popupConfigApply { wi object_type target phase } {
link { link {
global g_link_config_uni_state global g_link_config_uni_state
set mirror [getLinkMirror $target] set mirror [getLinkMirror $target]
if { [setIfChanged $target $mirror $wi "bandwidth" "LinkBandwidth"] } { if { [setIfChanged $target $mirror $wi "bandwidth" "LinkBandwidth"] } {
set changed 1 set changed 1
} }
@ -3314,7 +3314,7 @@ proc setIfChanged { target mirror wi ctl procname } {
# printCanvas $w # printCanvas $w
# FUNCTION # FUNCTION
# This procedure is called when the print button in # This procedure is called when the print button in
# print dialog box is pressed. # print dialog box is pressed.
# INPUTS # INPUTS
# * w -- print dialog widget # * w -- print dialog widget
#**** #****
@ -3335,12 +3335,12 @@ proc printCanvas { w } {
# SYNOPSIS # SYNOPSIS
# deleteSelection # deleteSelection
# FUNCTION # FUNCTION
# By calling this procedure all the selected nodes in imunes will # By calling this procedure all the selected nodes in imunes will
# be deleted. # be deleted.
#**** #****
proc deleteSelection { } { proc deleteSelection { } {
global changed global changed
global background global background
global viewid global viewid
catch {unset viewid} catch {unset viewid}
.c config -cursor watch; update .c config -cursor watch; update
@ -3412,7 +3412,7 @@ proc align2grid {} {
# FUNCTION # FUNCTION
# This procedure rearranges the position of nodes in imunes. # This procedure rearranges the position of nodes in imunes.
# It can be used to rearrange all the nodes or only the selected # It can be used to rearrange all the nodes or only the selected
# nodes. # nodes.
# INPUTS # INPUTS
# * mode -- when set to "selected" only the selected nodes will be # * mode -- when set to "selected" only the selected nodes will be
# rearranged. # rearranged.
@ -3594,16 +3594,16 @@ proc rearrange_off { } {
} }
#****f* editor.tcl/switchCanvas #****f* editor.tcl/switchCanvas
# NAME # NAME
# switchCanvas -- switch canvas # switchCanvas -- switch canvas
# SYNOPSIS # SYNOPSIS
# switchCanvas $direction # switchCanvas $direction
# FUNCTION # FUNCTION
# This procedure switches the canvas in one of the defined # This procedure switches the canvas in one of the defined
# directions (previous, next, first and last). # directions (previous, next, first and last).
# INPUTS # INPUTS
# * direction -- the direction of switching canvas. Can be: prev -- # * direction -- the direction of switching canvas. Can be: prev --
# previus, next -- next, first -- first, last -- last. # previus, next -- next, first -- first, last -- last.
#**** #****
proc switchCanvas { direction } { proc switchCanvas { direction } {
@ -3706,7 +3706,7 @@ proc resizeCanvasPopup {} {
labelframe $w.size -text "Size" labelframe $w.size -text "Size"
frame $w.size.pixels frame $w.size.pixels
pack $w.size $w.size.pixels -side top -padx 4 -pady 4 -fill x pack $w.size $w.size.pixels -side top -padx 4 -pady 4 -fill x
spinbox $w.size.pixels.x -bg white -width 5 spinbox $w.size.pixels.x -bg white -width 5
$w.size.pixels.x insert 0 $x $w.size.pixels.x insert 0 $x
$w.size.pixels.x configure -from 300 -to 5000 -increment 2 $w.size.pixels.x configure -from 300 -to 5000 -increment 2
@ -3717,10 +3717,10 @@ proc resizeCanvasPopup {} {
label $w.size.pixels.label2 -text "H pixels" label $w.size.pixels.label2 -text "H pixels"
pack $w.size.pixels.x $w.size.pixels.label $w.size.pixels.y \ pack $w.size.pixels.x $w.size.pixels.label $w.size.pixels.y \
$w.size.pixels.label2 -side left -pady 2 -padx 2 -fill x $w.size.pixels.label2 -side left -pady 2 -padx 2 -fill x
frame $w.size.meters frame $w.size.meters
pack $w.size.meters -side top -padx 4 -pady 4 -fill x pack $w.size.meters -side top -padx 4 -pady 4 -fill x
spinbox $w.size.meters.x -bg white -width 7 spinbox $w.size.meters.x -bg white -width 7
$w.size.meters.x configure -from 300 -to 10000 -increment 100 $w.size.meters.x configure -from 300 -to 10000 -increment 100
label $w.size.meters.label -text "x" label $w.size.meters.label -text "x"
spinbox $w.size.meters.y -bg white -width 7 spinbox $w.size.meters.y -bg white -width 7
@ -3789,7 +3789,7 @@ proc resizeCanvasPopup {} {
checkbutton $w.default.save -text "Save as default" \ checkbutton $w.default.save -text "Save as default" \
-variable resize_canvas_save_default -variable resize_canvas_save_default
pack $w.default.save -side left -pady 2 -padx 2 -fill x pack $w.default.save -side left -pady 2 -padx 2 -fill x
pack $w.default -side bottom -fill x pack $w.default -side bottom -fill x
# update the size in meters based on pixels # update the size in meters based on pixels
syncSizeScale $w xp syncSizeScale $w xp
@ -3884,7 +3884,7 @@ proc resizeCanvasApply { w } {
# SYNOPSIS # SYNOPSIS
# animate # animate
# FUNCTION # FUNCTION
# This function animates the selectbox. The animation looks # This function animates the selectbox. The animation looks
# different for edit and exec mode. # different for edit and exec mode.
#**** #****
proc animate {} { proc animate {} {
@ -3929,7 +3929,7 @@ proc zoom { dir } {
set newzoom $z set newzoom $z
} }
} }
set zoom $newzoom set zoom $newzoom
} }
redrawAll redrawAll
} }
@ -3945,7 +3945,7 @@ proc zoom { dir } {
break break
} }
} }
set zoom $newzoom set zoom $newzoom
} }
redrawAll redrawAll
} }
@ -3965,7 +3965,7 @@ proc zoom { dir } {
# SYNOPSIS # SYNOPSIS
# double1onGrid $c %x %y # double1onGrid $c %x %y
# FUNCTION # FUNCTION
# As grid is layered above annotations this procedure is used to find # As grid is layered above annotations this procedure is used to find
# annotation object closest to cursor # annotation object closest to cursor
#**** #****
@ -3977,7 +3977,7 @@ proc double1onGrid { c x y } {
return return
} }
# Is this really necessary? # Is this really necessary?
set coords [getNodeCoords $node] set coords [getNodeCoords $node]
set x1 [lindex $coords 0] set x1 [lindex $coords 0]
set y1 [lindex $coords 1] set y1 [lindex $coords 1]
set x2 [lindex $coords 2] set x2 [lindex $coords 2]
@ -4065,7 +4065,7 @@ proc configRemoteServers {} {
frame $wi.s -borderwidth 4 frame $wi.s -borderwidth 4
listbox $wi.s.servers -selectmode single -width 60 \ listbox $wi.s.servers -selectmode single -width 60 \
-yscrollcommand "$wi.s.servers_scroll set" -exportselection 0 -yscrollcommand "$wi.s.servers_scroll set" -exportselection 0
scrollbar $wi.s.servers_scroll -command "$wi.s.servers yview" scrollbar $wi.s.servers_scroll -command "$wi.s.servers yview"
pack $wi.s.servers $wi.s.servers_scroll -fill both -side left pack $wi.s.servers $wi.s.servers_scroll -fill both -side left
pack $wi.s -fill both -side top pack $wi.s -fill both -side top
# add scrollbar # add scrollbar
@ -4095,9 +4095,9 @@ proc configRemoteServers {} {
button $wi.c.c.add -image $plugin_img_add \ button $wi.c.c.add -image $plugin_img_add \
-command "configRemoteServersHelper $wi 1" -command "configRemoteServersHelper $wi 1"
button $wi.c.c.mod -image $plugin_img_save \ button $wi.c.c.mod -image $plugin_img_save \
-command "configRemoteServersHelper $wi 2" -command "configRemoteServersHelper $wi 2"
button $wi.c.c.del -image $plugin_img_del \ button $wi.c.c.del -image $plugin_img_del \
-command "configRemoteServersHelper $wi 3" -command "configRemoteServersHelper $wi 3"
pack $wi.c.c.add $wi.c.c.mod $wi.c.c.del -side left pack $wi.c.c.add $wi.c.c.mod $wi.c.c.del -side left
pack $wi.c -fill x -side top pack $wi.c -fill x -side top
# assignment buttons # assignment buttons
@ -4134,7 +4134,7 @@ proc configRemoteServers {} {
# apply/cancel buttons # apply/cancel buttons
frame $wi.b -borderwidth 4 frame $wi.b -borderwidth 4
button $wi.b.apply -text "Apply" -command \ button $wi.b.apply -text "Apply" -command \
"writeServersConf; redrawAll; destroy $wi" "writeServersConf; redrawAll; destroy $wi"
button $wi.b.cancel -text "Cancel" -command "loadServersConf; destroy $wi" button $wi.b.cancel -text "Cancel" -command "loadServersConf; destroy $wi"
pack $wi.b.cancel $wi.b.apply -side right pack $wi.b.cancel $wi.b.apply -side right
pack $wi.b -side bottom pack $wi.b -side bottom
@ -4169,7 +4169,7 @@ proc configRemoteServersHelper { wi action } {
set newserver [$wi.c.c.name get] set newserver [$wi.c.c.name get]
$wi.s.servers insert $index $newserver $wi.s.servers insert $index $newserver
# update the array # update the array
set conf [list [$wi.c.c.ip get] [$wi.c.c.port get]] set conf [list [$wi.c.c.ip get] [$wi.c.c.port get]]
array set exec_servers [list $newserver $conf] array set exec_servers [list $newserver $conf]
$wi.s.servers selection set $index $wi.s.servers selection set $index
set last_server_selected $index set last_server_selected $index
@ -4183,7 +4183,7 @@ proc selectRemoteServer { wi } {
# clear entries # clear entries
$wi.c.c.name delete 0 end; $wi.c.c.ip delete 0 end; $wi.c.c.name delete 0 end; $wi.c.c.ip delete 0 end;
$wi.c.c.port delete 0 end $wi.c.c.port delete 0 end
set server [$wi.s.servers get $selected] set server [$wi.s.servers get $selected]
if { ![info exists exec_servers($server)] } { return } if { ![info exists exec_servers($server)] } { return }
@ -4215,7 +4215,7 @@ proc popupCustomImage { node } {
set wi .customimagedialog set wi .customimagedialog
catch {destroy $wi} catch {destroy $wi}
toplevel $wi -takefocus 1 toplevel $wi -takefocus 1
wm transient $wi .popup wm transient $wi .popup
wm resizable $wi 0 0 wm resizable $wi 0 0
wm title $wi "[getNodeName $node] ($node) image" wm title $wi "[getNodeName $node] ($node) image"
grab $wi grab $wi
@ -4228,11 +4228,11 @@ proc popupCustomImage { node } {
global configwin global configwin
set configwin $wi set configwin $wi
button $wi.ftop.filebtn -text "..." -command { button $wi.ftop.filebtn -text "..." -command {
global configwin g_imageFileTypes global configwin g_imageFileTypes
set f [tk_getOpenFile -filetypes $g_imageFileTypes \ set f [tk_getOpenFile -filetypes $g_imageFileTypes \
-initialdir "$CORE_DATA_DIR/icons/normal"] -initialdir "$CORE_DATA_DIR/icons/normal"]
if { $f != "" } { if { $f != "" } {
set node [string trim [lindex [wm title $configwin] 1] "()"] set node [string trim [lindex [wm title $configwin] 1] "()"]
$configwin.ftop.filename delete 0 end $configwin.ftop.filename delete 0 end
$configwin.ftop.filename insert 0 $f $configwin.ftop.filename insert 0 $f
@ -4271,7 +4271,7 @@ proc popupCustomImagePreview { wi node } {
setNodeCoords $node "150 50" setNodeCoords $node "150 50"
setNodeLabelCoords $node "150 78" setNodeLabelCoords $node "150 78"
if { $img_save != $img_new } { setCustomImage $node $img_new } if { $img_save != $img_new } { setCustomImage $node $img_new }
$wi.fmid.c delete all $wi.fmid.c delete all
drawNode $wi.fmid.c $node drawNode $wi.fmid.c $node
@ -4363,9 +4363,9 @@ proc markerOptions { show } {
# Boeing: draw the marker sizes tool on a small canvas # Boeing: draw the marker sizes tool on a small canvas
proc drawMarkerSizes { c sel } { proc drawMarkerSizes { c sel } {
# determine the coordinates of the selection box based on value of sel # determine the coordinates of the selection box based on value of sel
if { $sel == 1 } { set coords {0 0 16 16} if { $sel == 1 } { set coords {0 0 16 16}
} elseif { $sel == 2 } { set coords {16 0 32 16} } elseif { $sel == 2 } { set coords {16 0 32 16}
} elseif { $sel == 3 } { set coords {0 16 16 32} } elseif { $sel == 3 } { set coords {0 16 16 32}
} else { set coords {16 16 32 32} } } else { set coords {16 16 32 32} }
# draw the selection box # draw the selection box
$c create rectangle $coords -fill gray -tag square -width 0 $c create rectangle $coords -fill gray -tag square -width 0
@ -4393,18 +4393,18 @@ proc markerSize { x y } {
drawMarkerSizes .left.markeropt.sizes $sel drawMarkerSizes .left.markeropt.sizes $sel
} }
# Boeing: set canvas wallpaper # Boeing: set canvas wallpaper
proc wallpaperPopup {} { proc wallpaperPopup {} {
global curcanvas global curcanvas
set w .wallpaperDlg set w .wallpaperDlg
catch {destroy $w} catch {destroy $w}
toplevel $w toplevel $w
wm transient $w . wm transient $w .
wm title $w "Set Canvas Wallpaper" wm title $w "Set Canvas Wallpaper"
grab $w grab $w
# preview # preview
canvas $w.preview -background white -relief sunken -width 200 -height 100 \ canvas $w.preview -background white -relief sunken -width 200 -height 100 \
-borderwidth 1 -borderwidth 1
@ -4421,7 +4421,7 @@ proc wallpaperPopup {} {
# file browse button # file browse button
global configwin global configwin
set configwin $w set configwin $w
button $w.f.filebtn -text "..." -command { button $w.f.filebtn -text "..." -command {
global configwin showGrid adjustCanvas fileDialogBox_initial global configwin showGrid adjustCanvas fileDialogBox_initial
global g_imageFileTypes global g_imageFileTypes
# use default conf file path upon first run # use default conf file path upon first run
@ -4443,7 +4443,7 @@ proc wallpaperPopup {} {
} }
# clear wallpaper button # clear wallpaper button
button $w.f.clear -text "clear" -command { button $w.f.clear -text "clear" -command {
global configwin wallpaperStyle global configwin wallpaperStyle
$configwin.f.file delete 0 end $configwin.f.file delete 0 end
$configwin.preview delete "wallpaper" $configwin.preview delete "wallpaper"
@ -4493,11 +4493,11 @@ proc wallpaperPopup {} {
# buttons # buttons
frame $w.btns frame $w.btns
button $w.btns.apply -text "Apply" -command { button $w.btns.apply -text "Apply" -command {
global configwin wallpaperStyle curcanvas adjustCanvas global configwin wallpaperStyle curcanvas adjustCanvas
set f [$configwin.f.file get] set f [$configwin.f.file get]
if {$adjustCanvas} { if {$adjustCanvas} {
wallpaperAdjustCanvas $curcanvas $f $wallpaperStyle wallpaperAdjustCanvas $curcanvas $f $wallpaperStyle
} }
setCanvasWallpaper $curcanvas $f $wallpaperStyle setCanvasWallpaper $curcanvas $f $wallpaperStyle
redrawAll redrawAll
@ -4536,7 +4536,7 @@ proc wallpaperAdjustCanvas { c f style } {
#puts -nonewline "wallpaperAdjustCanvas img($imgx, $imgy) $cx, $cy -> " #puts -nonewline "wallpaperAdjustCanvas img($imgx, $imgy) $cx, $cy -> "
# For scaled and tiled styles, expand canvas x and y to a multiple of # For scaled and tiled styles, expand canvas x and y to a multiple of
# imgx, imgy for better stretching. If the image is larger than the canvas, # imgx, imgy for better stretching. If the image is larger than the canvas,
# just increase the canvas size to accomodate it. # just increase the canvas size to accomodate it.
if {$style == "scaled" || $style == "tiled"} { if {$style == "scaled" || $style == "tiled"} {
@ -4605,13 +4605,13 @@ proc drawWallpaper { c f style } {
# grow image # grow image
if { $cx >= $imgx || $cy > $imgy } { if { $cx >= $imgx || $cy > $imgy } {
set x [expr 1+($cx / $imgx)] set x [expr 1+($cx / $imgx)]
set y [expr 1+($cy / $imgy)] set y [expr 1+($cy / $imgy)]
$img2 copy $img -zoom $x $y $img2 copy $img -zoom $x $y
# shrink image # shrink image
} else { } else {
$img2 copy $img -subsample \ $img2 copy $img -subsample \
[expr { int($imgx / $cx) }] \ [expr { int($imgx / $cx) }] \
[expr { int($imgy / $cy) }] [expr { int($imgy / $cy) }]
} }
$c create image [expr 1+$cx/2] [expr 1+$cy/2] -image $img2 \ $c create image [expr 1+$cx/2] [expr 1+$cy/2] -image $img2 \
-tags "background wallpaper" -tags "background wallpaper"
@ -4635,7 +4635,7 @@ proc drawWallpaper { c f style } {
} }
raiseAll $c raiseAll $c
} }
# helper for close/cancel buttons # helper for close/cancel buttons
@ -4665,11 +4665,11 @@ proc rj45ifclist { wi node wasclicked } {
listbox $wi.ftop.ifc.ifc_list -height 4 -width 30 \ listbox $wi.ftop.ifc.ifc_list -height 4 -width 30 \
-selectmode browse -yscrollcommand "$wi.ftop.ifc.ifc_scroll set" -selectmode browse -yscrollcommand "$wi.ftop.ifc.ifc_scroll set"
scrollbar $wi.ftop.ifc.ifc_scroll \ scrollbar $wi.ftop.ifc.ifc_scroll \
-command "$wi.ftop.ifc.ifc_list yview" -command "$wi.ftop.ifc.ifc_list yview"
set ifname "" set ifname ""
set ifip "" set ifip ""
# this handles differences between Linux and FreeBSD ifconfig # this handles differences between ifconfig
foreach line [split [nexec localnode ifconfig -a] "\n"] { foreach line [split [nexec localnode ifconfig -a] "\n"] {
set char [string index $line 0] set char [string index $line 0]
if { $char != " " && $char != " " } { if { $char != " " && $char != " " } {
@ -4924,7 +4924,7 @@ proc popupHookScript { name } {
"genericOpenSaveButtonPress $c $wi.mid.script $wi.n.name" "genericOpenSaveButtonPress $c $wi.mid.script $wi.n.name"
} }
ttk::combobox $wi.n.state -width 15 -state readonly -exportselection 0 \ ttk::combobox $wi.n.state -width 15 -state readonly -exportselection 0 \
-values $CORE_STATES -values $CORE_STATES
pack $wi.n.lab $wi.n.name -padx 4 -pady 4 -side left pack $wi.n.lab $wi.n.name -padx 4 -pady 4 -side left
pack $wi.n.open $wi.n.save -pady 4 -side left pack $wi.n.open $wi.n.save -pady 4 -side left
pack $wi.n.state -padx 4 -pady 4 -side left pack $wi.n.state -padx 4 -pady 4 -side left
@ -5081,7 +5081,7 @@ proc popupFileView { pathname } {
ttk::label $wi.top.fnl -text "File:" ttk::label $wi.top.fnl -text "File:"
ttk::entry $wi.top.fn ttk::entry $wi.top.fn
#ttk::entry $wi.top.fn -state readonly #ttk::entry $wi.top.fn -state readonly
pack $wi.top.fnl -padx 4 -side left pack $wi.top.fnl -padx 4 -side left
pack $wi.top.fn -padx 4 -side left -fill both -expand true pack $wi.top.fn -padx 4 -side left -fill both -expand true
pack $wi.top -padx 4 -pady 4 -side top -fill both -expand true pack $wi.top -padx 4 -pady 4 -side top -fill both -expand true
$wi.top.fn insert 0 $pathname $wi.top.fn insert 0 $pathname

View file

@ -38,10 +38,10 @@
# SYNOPSIS # SYNOPSIS
# set result [nexec $args] # set result [nexec $args]
# FUNCTION # FUNCTION
# Executes the sting given in args variable. The sting is not executed # Executes the sting given in args variable. The sting is not executed
# if IMUNES is running in editor only mode. Execution of a string can # if IMUNES is running in editor only mode. Execution of a string can
# be local or remote. If socket can not be opened in try of a remote # be local or remote. If socket can not be opened in try of a remote
# execution, mode is switched to editor only mode. # execution, mode is switched to editor only mode.
# INPUTS # INPUTS
# * args -- the string that should be executed localy or remotely. # * args -- the string that should be executed localy or remotely.
# RESULT # RESULT
@ -80,7 +80,7 @@ proc acquireOperModeLock { mode } {
if { $mode == "exec" } { if { $mode == "exec" } {
set choice [tk_messageBox -type yesno -default no -icon warning \ set choice [tk_messageBox -type yesno -default no -icon warning \
-message "You have selected to start the session while the previous one is still shutting down. Are you sure you want to interrupt the shutdown? (not recommended)"] -message "You have selected to start the session while the previous one is still shutting down. Are you sure you want to interrupt the shutdown? (not recommended)"]
if { $choice == "no" } { if { $choice == "no" } {
set activetool select set activetool select
return; # return and allow previous setOperMode to finish... return; # return and allow previous setOperMode to finish...
} }
@ -88,7 +88,7 @@ proc acquireOperModeLock { mode } {
} elseif { $setOperMode_lock } { ;# mode == "edit" } elseif { $setOperMode_lock } { ;# mode == "edit"
set choice [tk_messageBox -type yesno -default no -icon warning \ set choice [tk_messageBox -type yesno -default no -icon warning \
-message "You are trying to stop the session while it is still starting. Are you sure you want to interrupt the startup? (not recommeded)"] -message "You are trying to stop the session while it is still starting. Are you sure you want to interrupt the startup? (not recommeded)"]
if { $choice == "no" } { if { $choice == "no" } {
set activetool select set activetool select
return; # return and allow previous setOperMode to finish... return; # return and allow previous setOperMode to finish...
} }
@ -155,7 +155,7 @@ proc drawToolbar { mode } {
# add buttons when in edit mode # add buttons when in edit mode
set imgf "$CORE_DATA_DIR/icons/tiny/$b.gif" set imgf "$CORE_DATA_DIR/icons/tiny/$b.gif"
set image [image create photo -file $imgf] set image [image create photo -file $imgf]
catch { catch {
radiobutton .left.$b -indicatoron 0 \ radiobutton .left.$b -indicatoron 0 \
-variable activetool -value $b -selectcolor $defSelectionColor \ -variable activetool -value $b -selectcolor $defSelectionColor \
-width 32 -height 32 -image $image \ -width 32 -height 32 -image $image \
@ -163,7 +163,7 @@ proc drawToolbar { mode } {
leftToolTip $b .left leftToolTip $b .left
pack .left.$b -side top pack .left.$b -side top
} }
} }
} }
# popup toolbar buttons have submenus # popup toolbar buttons have submenus
set buttons {routers hubs bgobjs} set buttons {routers hubs bgobjs}
@ -192,7 +192,7 @@ proc drawToolbar { mode } {
-borderwidth 1 -tearoff 0] -borderwidth 1 -tearoff 0]
# create the child menutbuttons # create the child menutbuttons
drawToolbarSubmenu $b $menubuttons drawToolbarSubmenu $b $menubuttons
# tooltips for parent and submenu items # tooltips for parent and submenu items
leftToolTip $b .left leftToolTip $b .left
bind $buttonmenu <<MenuSelect>> {leftToolTipSubMenu %W} bind $buttonmenu <<MenuSelect>> {leftToolTipSubMenu %W}
bind $buttonmenu <Leave> { bind $buttonmenu <Leave> {
@ -206,7 +206,7 @@ proc drawToolbar { mode } {
} }
} }
# #
# Exec mode button bar # Exec mode button bar
# #
if { "$mode" == "edit" } { if { "$mode" == "edit" } {
@ -267,7 +267,7 @@ proc drawToolbarSubmenu { b menubuttons } {
$buttonmenu add command -image $img -columnbreak 1 \ $buttonmenu add command -image $img -columnbreak 1 \
-command "popupMenuChoose $b $menubutton $imgf" -command "popupMenuChoose $b $menubutton $imgf"
} }
# add an edit button to the end of the row # add an edit button to the end of the row
if { $b == "routers" } { if { $b == "routers" } {
set imgf "$CORE_DATA_DIR/icons/normal/document-properties.gif" set imgf "$CORE_DATA_DIR/icons/normal/document-properties.gif"
set img [createImageButton $imgf 0] set img [createImageButton $imgf 0]
@ -279,7 +279,7 @@ proc drawToolbarSubmenu { b menubuttons } {
proc setSessionStartStopMenu { mode } { proc setSessionStartStopMenu { mode } {
if { $mode == "exec" } { if { $mode == "exec" } {
catch {.menubar.session entryconfigure "Start" \ catch {.menubar.session entryconfigure "Start" \
-label "Stop" -command "startStopButton edit"} -label "Stop" -command "startStopButton edit"}
} else { } else {
catch {.menubar.session entryconfigure "Stop" \ catch {.menubar.session entryconfigure "Stop" \
-label "Start" -command "startStopButton exec"} -label "Start" -command "startStopButton exec"}
@ -339,8 +339,8 @@ proc startStopButton { mode } {
# Sets imunes operating mode to the value of the parameter mode. # Sets imunes operating mode to the value of the parameter mode.
# The mode can be set only to edit or exec. # The mode can be set only to edit or exec.
# When changing the mode to exec all the emulation interfaces are # When changing the mode to exec all the emulation interfaces are
# checked (if they are nonexistent the message is displayed, and # checked (if they are nonexistent the message is displayed, and
# mode is not changed), all the required buttons are disabled # mode is not changed), all the required buttons are disabled
# (except the simulation/Terminate button, that is enabled) and # (except the simulation/Terminate button, that is enabled) and
# procedure deployCfg is called. # procedure deployCfg is called.
# When changing the mode to edit, all required buttons are enabled # When changing the mode to edit, all required buttons are enabled
@ -387,7 +387,7 @@ proc setOperMode { mode { type "" } } {
# #
# Start/stop the emulation # Start/stop the emulation
# #
### start button is pressed ### start button is pressed
if { "$mode" == "exec" } { if { "$mode" == "exec" } {
rearrange_off rearrange_off
@ -395,11 +395,11 @@ proc setOperMode { mode { type "" } } {
resetAllNodeCoords save resetAllNodeCoords save
clearExceptions "" "" clearExceptions "" ""
throwCEL true throwCEL true
# Bind left mouse click to displaying the CPU usage in # Bind left mouse click to displaying the CPU usage in
# a graph format # a graph format
bind .bottom.cpu_load <1> {manageCPUwindow %X %Y 1} bind .bottom.cpu_load <1> {manageCPUwindow %X %Y 1}
monitor_loop monitor_loop
set plugin [lindex [getEmulPlugin "*"] 0] set plugin [lindex [getEmulPlugin "*"] 0]
set emul_sock [pluginConnect $plugin connect false] set emul_sock [pluginConnect $plugin connect false]
@ -422,7 +422,7 @@ proc setOperMode { mode { type "" } } {
clearWlanLinks "" clearWlanLinks ""
widgets_stop widgets_stop
set oper_mode edit set oper_mode edit
# Bind left mouse click to clearing the CPU graph # Bind left mouse click to clearing the CPU graph
bind .bottom.cpu_load <1> {manageCPUwindow %X %Y 0} bind .bottom.cpu_load <1> {manageCPUwindow %X %Y 0}
manageCPUwindow %X %Y 0 manageCPUwindow %X %Y 0
@ -438,7 +438,7 @@ proc setOperMode { mode { type "" } } {
# SYNOPSIS # SYNOPSIS
# statline $line # statline $line
# FUNCTION # FUNCTION
# Sets the string of the status line. If the execution mode is # Sets the string of the status line. If the execution mode is
# set to batch the line is just printed on the standard output. # set to batch the line is just printed on the standard output.
# INPUTS # INPUTS
# * line -- line to be displayed # * line -- line to be displayed
@ -475,15 +475,15 @@ proc getNextMac {} {
# monitor_loop # monitor_loop
# FUNCTION # FUNCTION
# Calculates the usage of cpu, mbuffers and mbuf clusters. # Calculates the usage of cpu, mbuffers and mbuf clusters.
# The results are displayed in status line and updated # The results are displayed in status line and updated
# every two seconds. # every two seconds.
#**** #****
proc monitor_loop {} { proc monitor_loop {} {
global oper_mode systype global oper_mode systype
global server_cpuusage global server_cpuusage
global exec_servers global exec_servers
if {$oper_mode != "exec"} { if {$oper_mode != "exec"} {
.bottom.cpu_load config -text "" .bottom.cpu_load config -text ""
.bottom.mbuf config -text "" .bottom.mbuf config -text ""
@ -492,7 +492,7 @@ proc monitor_loop {} {
if { [lindex $systype 0] == "Linux" } { if { [lindex $systype 0] == "Linux" } {
set cpuusage [getCPUUsage] set cpuusage [getCPUUsage]
#TODO: get the cpu usage on all the assigned server #TODO: get the cpu usage on all the assigned server
# store usage history for each server stored in an array list # store usage history for each server stored in an array list
set assigned_servers [getAssignedRemoteServers] set assigned_servers [getAssignedRemoteServers]
@ -509,22 +509,22 @@ proc monitor_loop {} {
# TODO: receive CPU usage from other servers # TODO: receive CPU usage from other servers
set cpuusageforserver 0 set cpuusageforserver 0
} }
# append the latest cpu value to the end of list and # append the latest cpu value to the end of list and
# only keep and display the last 20 values for each server # only keep and display the last 20 values for each server
set server_cpuusage($ip) [lappend server_cpuusage($ip) $cpuusageforserver] set server_cpuusage($ip) [lappend server_cpuusage($ip) $cpuusageforserver]
if { [llength $server_cpuusage($ip)] > 20 } { if { [llength $server_cpuusage($ip)] > 20 } {
set server_cpuusage($ip) [lreplace $server_cpuusage($ip) 0 0] set server_cpuusage($ip) [lreplace $server_cpuusage($ip) 0 0]
} }
} }
#plot the usage data if cpu windows already opened #plot the usage data if cpu windows already opened
# for all servers # for all servers
if { [winfo exists .cpu]} { if { [winfo exists .cpu]} {
plotCPUusage plotCPUusage
} }
set cputxt "CPU [lindex $cpuusage 0]% (" set cputxt "CPU [lindex $cpuusage 0]% ("
set cpuusage [lreplace $cpuusage 0 0] set cpuusage [lreplace $cpuusage 0 0]
for { set n 0 } { $n < [llength $cpuusage] } { incr n } { for { set n 0 } { $n < [llength $cpuusage] } { incr n } {
@ -544,13 +544,8 @@ proc monitor_loop {} {
return return
} }
if { $systype == "FreeBSD 4.11-RELEASE" } { set defaultname "."
set defaultname "default"
set cpun 3
} else {
set defaultname "."
set cpun 4 set cpun 4
}
# CPU usage from `vimage -l` # CPU usage from `vimage -l`
set vimagetext [nexec localnode vimage -l $defaultname | xargs] set vimagetext [nexec localnode vimage -l $defaultname | xargs]
@ -578,7 +573,7 @@ proc monitor_loop {} {
# SYNOPSIS # SYNOPSIS
# execSetLinkParams $eid $link # execSetLinkParams $eid $link
# FUNCTION # FUNCTION
# Sets the link parameters during execution. # Sets the link parameters during execution.
# All the parameters are set at the same time. # All the parameters are set at the same time.
# INPUTS # INPUTS
# eid -- experiment id # eid -- experiment id
@ -649,7 +644,7 @@ proc createImageButton { imgf style } {
} }
} }
return $img return $img
} }
# Boeing: status bar graph # Boeing: status bar graph
@ -689,7 +684,7 @@ proc statgraph { cmd n } {
} }
} }
} }
proc popupConnectMessage { dst } { proc popupConnectMessage { dst } {
global CORE_DATA_DIR execMode global CORE_DATA_DIR execMode
@ -751,21 +746,21 @@ proc manageCPUwindow {xpos ypos start} {
global exec_servers global exec_servers
global server_cpuusage global server_cpuusage
if {$start == 1} { if {$start == 1} {
if { ![winfo exists .cpu]} { if { ![winfo exists .cpu]} {
toplevel .cpu toplevel .cpu
wm geometry .cpu 200x210+$xpos+$ypos wm geometry .cpu 200x210+$xpos+$ypos
wm resizable .cpu 0 0 wm resizable .cpu 0 0
wm title .cpu "CPU Usage" wm title .cpu "CPU Usage"
canvas .cpu.graph -width 200 -height 210 canvas .cpu.graph -width 200 -height 210
pack .cpu.graph pack .cpu.graph
} }
} else { } else {
if { [winfo exists .cpu]} { if { [winfo exists .cpu]} {
destroy .cpu destroy .cpu
set assigned_servers [getAssignedRemoteServers] set assigned_servers [getAssignedRemoteServers]
for {set i 0} {$i <= [llength $assigned_servers]} {incr i} { for {set i 0} {$i <= [llength $assigned_servers]} {incr i} {
if {$i == [llength $assigned_servers]} { if {$i == [llength $assigned_servers]} {
set ip [getMyIP] set ip [getMyIP]
@ -774,7 +769,7 @@ proc manageCPUwindow {xpos ypos start} {
set srv [array get exec_servers $server] set srv [array get exec_servers $server]
if { $srv == "" } { continue } if { $srv == "" } { continue }
set ip [lindex $srv 0] set ip [lindex $srv 0]
} }
set server_cpuusage($ip) [lreplace $server_cpuusage($ip) 0 end] set server_cpuusage($ip) [lreplace $server_cpuusage($ip) 0 end]
} }
} }
@ -789,7 +784,7 @@ proc getMyIP { } {
set myIP [lindex [fconfigure $theServer -sockname] 0] set myIP [lindex [fconfigure $theServer -sockname] 0]
close $theServer close $theServer
return $myIP return $myIP
} }
# display all values stored in cpu usage history for each server # display all values stored in cpu usage history for each server
@ -797,24 +792,24 @@ proc plotCPUusage { } {
global cpu_palettes global cpu_palettes
global exec_servers global exec_servers
global server_cpuusage global server_cpuusage
.cpu.graph delete "all" .cpu.graph delete "all"
.cpu.graph create line 0 100 200 100 -width 2 .cpu.graph create line 0 100 200 100 -width 2
.cpu.graph create line 0 80 200 80 -width 1 .cpu.graph create line 0 80 200 80 -width 1
.cpu.graph create line 0 60 200 60 -width 1 .cpu.graph create line 0 60 200 60 -width 1
.cpu.graph create line 0 40 200 40 -width 1 .cpu.graph create line 0 40 200 40 -width 1
.cpu.graph create line 0 20 200 20 -width 1 .cpu.graph create line 0 20 200 20 -width 1
.cpu.graph create line 0 0 200 0 -width 1 .cpu.graph create line 0 0 200 0 -width 1
.cpu.graph create line 40 0 40 100 -width 1 .cpu.graph create line 40 0 40 100 -width 1
.cpu.graph create line 80 0 80 100 -width 1 .cpu.graph create line 80 0 80 100 -width 1
.cpu.graph create line 120 0 120 100 -width 1 .cpu.graph create line 120 0 120 100 -width 1
.cpu.graph create line 160 0 160 100 -width 1 .cpu.graph create line 160 0 160 100 -width 1
.cpu.graph create line 200 0 200 100 -width 1 .cpu.graph create line 200 0 200 100 -width 1
# for each server create a plot of cpu usage # for each server create a plot of cpu usage
set assigned_servers [getAssignedRemoteServers] set assigned_servers [getAssignedRemoteServers]
for {set i 0} {$i <= [llength $assigned_servers]} {incr i} { for {set i 0} {$i <= [llength $assigned_servers]} {incr i} {
if {$i == [llength $assigned_servers]} { if {$i == [llength $assigned_servers]} {
set ip [getMyIP] set ip [getMyIP]
} else { } else {
@ -823,9 +818,9 @@ proc plotCPUusage { } {
if { $srv == "" } { continue } if { $srv == "" } { continue }
set ip [lindex $srv 0] set ip [lindex $srv 0]
} }
#need to add multiple cpuusgaehistory (array) #need to add multiple cpuusgaehistory (array)
for { set n 1 } { $n < [llength $server_cpuusage($ip)] } { incr n } { for { set n 1 } { $n < [llength $server_cpuusage($ip)] } { incr n } {
set prevn [expr {$n - 1}] set prevn [expr {$n - 1}]
set x1 [expr {$prevn * 10}] set x1 [expr {$prevn * 10}]
set y1 [expr {100 - [lindex $server_cpuusage($ip) $prevn]}] set y1 [expr {100 - [lindex $server_cpuusage($ip) $prevn]}]
@ -837,15 +832,15 @@ proc plotCPUusage { } {
.cpu.graph create line $x1 $y1 $x2 $y2 -fill [lindex $cpu_palettes end] .cpu.graph create line $x1 $y1 $x2 $y2 -fill [lindex $cpu_palettes end]
} }
#debug #debug
#puts " cpu $x1 $y1 $x2 $y2" #puts " cpu $x1 $y1 $x2 $y2"
} }
#for each server create a legend (limited to 8) #for each server create a legend (limited to 8)
set legendtext $ip set legendtext $ip
append legendtext " " [lindex $server_cpuusage($ip) end] "%" append legendtext " " [lindex $server_cpuusage($ip) end] "%"
set legendy [expr {($i * 10) + 120}] set legendy [expr {($i * 10) + 120}]
set legendx 10 set legendx 10
if {$i < [llength $cpu_palettes]} { if {$i < [llength $cpu_palettes]} {
.cpu.graph create rectangle $legendx $legendy \ .cpu.graph create rectangle $legendx $legendy \
@ -861,9 +856,9 @@ proc plotCPUusage { } {
.cpu.graph create text [expr {$legendx + 15}] [expr {$legendy + 4}]\ .cpu.graph create text [expr {$legendx + 15}] [expr {$legendy + 4}]\
-text $legendtext -fill [lindex $cpu_palettes end] \ -text $legendtext -fill [lindex $cpu_palettes end] \
-anchor w -justify left -anchor w -justify left
} }
} }
} }

View file

@ -36,41 +36,41 @@
# NAME # NAME
# filemgmt.tcl -- file used for manipulation with files # filemgmt.tcl -- file used for manipulation with files
# FUNCTION # FUNCTION
# This module is used for all file manipulations. In this file # This module is used for all file manipulations. In this file
# a file is read, a new file opened or existing file saved. # a file is read, a new file opened or existing file saved.
# NOTES # NOTES
# variables: # variables:
# #
# currentFile # currentFile
# relative or absolute path to the current configuration file # relative or absolute path to the current configuration file
# #
# fileTypes # fileTypes
# types that will be displayed when opening new file # types that will be displayed when opening new file
# #
# procedures used for loading and storing the configuration file: # procedures used for loading and storing the configuration file:
# #
# newFile # newFile
# - creates an empty project # - creates an empty project
# #
# openFile {filename} # openFile {filename}
# - loads configuration from filename # - loads configuration from filename
# #
# saveFile {selectedFile} # saveFile {selectedFile}
# - saves current configuration to a file named selectedFile # - saves current configuration to a file named selectedFile
# unless the file name is an empty string # unless the file name is an empty string
# #
# fileOpenStartUp # fileOpenStartUp
# - opens the file named as command line argument # - opens the file named as command line argument
# #
# fileNewDialogBox # fileNewDialogBox
# - opens message box to optionally save the changes # - opens message box to optionally save the changes
# #
# fileOpenDialogBox # fileOpenDialogBox
# - opens dialog box for selecting a file to open # - opens dialog box for selecting a file to open
# #
# fileSaveDialogBox # fileSaveDialogBox
# - opens dialog box for saving a file under new name if there is no # - opens dialog box for saving a file under new name if there is no
# current file # current file
#**** #****
set currentFile "" set currentFile ""
@ -103,11 +103,6 @@ proc newFile {} {
set g_view_locked 0 set g_view_locked 0
# flush daemon configuration # flush daemon configuration
if { [llength [findWlanNodes ""]] > 0 } {
if { [lindex $systype 0] == "FreeBSD" } {
catch { exec ngctl config wlan_ctl: flush=all }
}
}
loadCfg "" loadCfg ""
resetGlobalVars newfile resetGlobalVars newfile
set curcanvas [lindex $canvas_list 0] set curcanvas [lindex $canvas_list 0]
@ -143,7 +138,7 @@ proc newFile {} {
# Loads the configuration from the file named $filename. # Loads the configuration from the file named $filename.
#**** #****
proc openFile { filename } { proc openFile { filename } {
global currentFile global currentFile
global undolog activetool global undolog activetool
global canvas_list curcanvas systype global canvas_list curcanvas systype
global changed global changed
@ -190,11 +185,6 @@ proc openFile { filename } {
} }
# flush daemon configuration # flush daemon configuration
if { [llength [findWlanNodes ""]] > 0 } {
if { [lindex $systype 0] == "FreeBSD" } {
catch { exec ngctl config wlan_ctl: flush=all }
}
}
set cfg "" set cfg ""
if { [catch { set fileId [open $currentFile r] } err] } { if { [catch { set fileId [open $currentFile r] } err] } {
puts "error opening file $currentFile: $err" puts "error opening file $currentFile: $err"
@ -209,7 +199,7 @@ proc openFile { filename } {
loadCfg $cfg loadCfg $cfg
switchCanvas none switchCanvas none
set undolog(0) $cfg set undolog(0) $cfg
set activetool select set activetool select
# remember opened files # remember opened files
@ -236,11 +226,11 @@ proc resetGlobalVars { reason } {
# FUNCTION # FUNCTION
# Loads the current configuration into the selectedFile file. # Loads the current configuration into the selectedFile file.
# INPUTS # INPUTS
# * selectedFile -- the name of the file where current # * selectedFile -- the name of the file where current
# configuration is saved. # configuration is saved.
#**** #****
proc saveFile { selectedFile } { proc saveFile { selectedFile } {
global currentFile global currentFile
global changed global changed
if { $selectedFile == ""} { if { $selectedFile == ""} {
@ -275,7 +265,7 @@ proc saveFile { selectedFile } {
# SYNOPSIS # SYNOPSIS
# fileOpenStartUp # fileOpenStartUp
# FUNCTION # FUNCTION
# Loads configuration from batch input file to the current # Loads configuration from batch input file to the current
# configuration. # configuration.
#**** #****
proc fileOpenStartUp {} { proc fileOpenStartUp {} {
@ -310,7 +300,7 @@ proc fileNewDialogBox {} {
if {$changed != 0 } { if {$changed != 0 } {
set choice [promptForSave] set choice [promptForSave]
} }
if { $choice != "cancel"} { if { $choice != "cancel"} {
newFile newFile
} }
@ -370,7 +360,7 @@ proc fileSaveDialogBox { prompt } {
set ft [lreplace $ft 0 0] set ft [lreplace $ft 0 0]
set ft [linsert $ft 1 $imn] set ft [linsert $ft 1 $imn]
} }
set dir "" set dir ""
# use default conf file path upon first run # use default conf file path upon first run
if { $fileDialogBox_initial == 0} { if { $fileDialogBox_initial == 0} {
@ -450,7 +440,7 @@ proc loadDotFile {} {
set isfile 0 set isfile 0
if {[catch {set dotfile [open "$CONFDIR/prefs.conf" r]} ]} return if {[catch {set dotfile [open "$CONFDIR/prefs.conf" r]} ]} return
close $dotfile close $dotfile
if {[catch { source "$CONFDIR/prefs.conf" }]} { if {[catch { source "$CONFDIR/prefs.conf" }]} {
puts "The $CONFDIR/prefs.conf preferences file is invalid, ignoring it." puts "The $CONFDIR/prefs.conf preferences file is invalid, ignoring it."
#file delete "~/.core" #file delete "~/.core"
@ -468,7 +458,7 @@ proc savePrefsFile { } {
# header # header
puts $dotfile "# CORE ${CORE_VERSION} GUI preference file" puts $dotfile "# CORE ${CORE_VERSION} GUI preference file"
# save the most-recently-used file list # save the most-recently-used file list
puts $dotfile "set g_mrulist \"$g_mrulist\"" puts $dotfile "set g_mrulist \"$g_mrulist\""
@ -550,10 +540,6 @@ proc exit {} {
if { [popupStopSessionPrompt]=="cancel" } { if { [popupStopSessionPrompt]=="cancel" } {
return return
} }
# Flush daemon configuration
if { [lindex $systype 0] == "FreeBSD" } {
catch { exec ngctl config wlan_ctl: flush=all }
}
# Prompt for save if file was changed # Prompt for save if file was changed
if { $changed != 0 && [promptForSave] == "cancel" } { if { $changed != 0 && [promptForSave] == "cancel" } {
return return
@ -579,7 +565,7 @@ proc exit {} {
# save user preferences # save user preferences
savePrefsFile savePrefsFile
exit.real exit.real
} }

View file

@ -35,11 +35,11 @@
# NAME # NAME
# linkcfg.tcl -- file used for manipultaion with links in IMUNES # linkcfg.tcl -- file used for manipultaion with links in IMUNES
# FUNCTION # FUNCTION
# This module is used to define all the actions used for configuring # This module is used to define all the actions used for configuring
# links in IMUNES. # links in IMUNES.
# #
# NOTES # NOTES
# #
# linkPeers { link_id } # linkPeers { link_id }
# Returns node_ids of link endpoints # Returns node_ids of link endpoints
# #
@ -53,7 +53,7 @@
# ... in bits per second # ... in bits per second
# #
# getLinkBandwidthString { link_id } # getLinkBandwidthString { link_id }
# ... as string # ... as string
# #
# getLinkDelay { link_id } # getLinkDelay { link_id }
# ... in microseconds # ... in microseconds
@ -83,7 +83,7 @@
# INPUTS # INPUTS
# * link_id -- link id # * link_id -- link id
# RESULT # RESULT
# * link_peers -- returns nodes_ids of a link endpoints # * link_peers -- returns nodes_ids of a link endpoints
# in a list {node1_id node2_id} # in a list {node1_id node2_id}
#**** #****
@ -100,14 +100,14 @@ proc linkPeers { link } {
# SYNOPSIS # SYNOPSIS
# set link_id [linkByPeers $node1_id $node2_id] # set link_id [linkByPeers $node1_id $node2_id]
# FUNCTION # FUNCTION
# Returns link_id whose peers are node1 and node2. # Returns link_id whose peers are node1 and node2.
# The order of input nodes is irrelevant. # The order of input nodes is irrelevant.
# INPUTS # INPUTS
# * node1_id -- node id of the first node # * node1_id -- node id of the first node
# * node2_id -- node id of the second node # * node2_id -- node id of the second node
# RESULT # RESULT
# * link_id -- returns id of a link connecting endpoints # * link_id -- returns id of a link connecting endpoints
# node1_id node2_id. # node1_id node2_id.
#**** #****
proc linkByPeers { node1 node2 } { proc linkByPeers { node1 node2 } {
@ -144,7 +144,7 @@ proc linkByPeersMirror { node1 node2 } {
# removeLink $link_id # removeLink $link_id
# FUNCTION # FUNCTION
# Removes the link and related entries in peering node's configs. # Removes the link and related entries in peering node's configs.
# Updates the default route for peer nodes. # Updates the default route for peer nodes.
# INPUTS # INPUTS
# * link_id -- link id # * link_id -- link id
#**** #****
@ -199,7 +199,7 @@ proc getLinkBandwidth { link {dir "down"} } {
# INPUTS # INPUTS
# * link_id -- link id # * link_id -- link id
# RESULT # RESULT
# * bandwidth_str -- The value of link bandwidth formated in a sting # * bandwidth_str -- The value of link bandwidth formated in a sting
# containing a measure unit. # containing a measure unit.
#**** #****
@ -332,7 +332,7 @@ proc getLinkDelay { link {dir "down"} } {
# INPUTS # INPUTS
# * link_id -- link id # * link_id -- link id
# RESULT # RESULT
# * delay -- The value of link delay formated in a string # * delay -- The value of link delay formated in a string
# containing a measure unit. # containing a measure unit.
#**** #****
@ -437,7 +437,7 @@ proc getLinkBERString { link } {
if { $ber != "" } { if { $ber != "" } {
set berstr "$berstr$ber%" set berstr "$berstr$ber%"
} }
if { $berup != "" } { if { $berup != "" } {
set berstr "$berstr / $berup%" set berstr "$berstr / $berup%"
} }
return $berstr return $berstr
@ -472,7 +472,7 @@ proc setLinkBER { link value } {
#****f* linkcfg.tcl/getLinkDup #****f* linkcfg.tcl/getLinkDup
# NAME # NAME
# getLinkDup -- get link packet duplicate value # getLinkDup -- get link packet duplicate value
# SYNOPSIS # SYNOPSIS
# set duplicate [getLinkDup $link_id] # set duplicate [getLinkDup $link_id]
# FUNCTION # FUNCTION
@ -508,7 +508,7 @@ proc getLinkDupString { link } {
#****f* linkcfg.tcl/setLinkDup #****f* linkcfg.tcl/setLinkDup
# NAME # NAME
# setLinkDup -- set link packet duplicate value # setLinkDup -- set link packet duplicate value
# SYNOPSIS # SYNOPSIS
# setLinkDup $link_id $value # setLinkDup $link_id $value
# FUNCTION # FUNCTION
@ -547,7 +547,7 @@ proc isLinkUni { link } {
#****f* linkcfg.tcl/getLinkMirror #****f* linkcfg.tcl/getLinkMirror
# NAME # NAME
# getLinkMirror -- get link's mirror link # getLinkMirror -- get link's mirror link
# SYNOPSIS # SYNOPSIS
# set mirror_link_id [getLinkMirror $link_id] # set mirror_link_id [getLinkMirror $link_id]
# FUNCTION # FUNCTION
@ -569,7 +569,7 @@ proc getLinkMirror { link } {
#****f* linkcfg.tcl/setLinkMirror #****f* linkcfg.tcl/setLinkMirror
# NAME # NAME
# setLinkMirror -- set link's mirror link # setLinkMirror -- set link's mirror link
# SYNOPSIS # SYNOPSIS
# setLinkMirror $link_id $mirror_link_id # setLinkMirror $link_id $mirror_link_id
# FUNCTION # FUNCTION
@ -599,7 +599,7 @@ proc setLinkMirror { link value } {
# SYNOPSIS # SYNOPSIS
# set nodes [splitLink $link_id $nodetype] # set nodes [splitLink $link_id $nodetype]
# FUNCTION # FUNCTION
# Splits the link in two parts. Each part of the split link is one # Splits the link in two parts. Each part of the split link is one
# pseudo link. # pseudo link.
# INPUTS # INPUTS
# * link_id -- link id # * link_id -- link id
@ -674,7 +674,7 @@ proc splitLink { link nodetype } {
# SYNOPSIS # SYNOPSIS
# set new_link_id [mergeLink $link_id] # set new_link_id [mergeLink $link_id]
# FUNCTION # FUNCTION
# Rebuilts a link from two pseudo link. # Rebuilts a link from two pseudo link.
# INPUTS # INPUTS
# * link_id -- pseudo link id # * link_id -- pseudo link id
# RESULT # RESULT
@ -754,11 +754,11 @@ proc newLink { lnode1 lnode2 } {
global systype global systype
if { ([nodeType $lnode1] == "lanswitch" ||[nodeType $lnode1] == "OVS") && \ if { ([nodeType $lnode1] == "lanswitch" ||[nodeType $lnode1] == "OVS") && \
[nodeType $lnode2] != "router" && \ [nodeType $lnode2] != "router" && \
([nodeType $lnode2] != "lanswitch" || [nodeType $lnode2] != "OVS") } { ([nodeType $lnode2] != "lanswitch" || [nodeType $lnode2] != "OVS") } {
set regular no } set regular no }
if { ([nodeType $lnode2] == "lanswitch" || [nodeType $lnode2] == "OVS") && \ if { ([nodeType $lnode2] == "lanswitch" || [nodeType $lnode2] == "OVS") && \
[nodeType $lnode1] != "router" && \ [nodeType $lnode1] != "router" && \
([nodeType $lnode1] != "lanswitch" || [nodeType $lnode1] != "OVS" )} { ([nodeType $lnode1] != "lanswitch" || [nodeType $lnode1] != "OVS" )} {
#Khaled: puts "connecting '$lnode1' (type: '[nodeType $lnode1]') to '$lnode2' (type: '[nodeType $lnode2]') " #Khaled: puts "connecting '$lnode1' (type: '[nodeType $lnode1]') to '$lnode2' (type: '[nodeType $lnode2]') "
set regular no } set regular no }
if { [nodeType $lnode1] == "hub" && \ if { [nodeType $lnode1] == "hub" && \
@ -839,15 +839,11 @@ proc newLink { lnode1 lnode2 } {
if { [string range $model 0 6] == "coreapi" } { if { [string range $model 0 6] == "coreapi" } {
set delay 0; # delay controlled by wireless module set delay 0; # delay controlled by wireless module
} elseif {$delay != ""} { } elseif {$delay != ""} {
if { [lindex $systype 0] == "FreeBSD" } {
lappend $link "delay [expr $delay/2]"
} else {
lappend $link "delay $delay" lappend $link "delay $delay"
} }
}
# Exclude OVS from network layer nodes IP address asignments # Exclude OVS from network layer nodes IP address asignments
if { ([[typemodel $lnode2].layer] == "NETWORK") && ([nodeType $lnode2] != "OVS") } { if { ([[typemodel $lnode2].layer] == "NETWORK") && ([nodeType $lnode2] != "OVS") } {
#Khaled: puts "Assigning '$lnode2' (type: '[nodeType $lnode2]') an automatic IP address" #Khaled: puts "Assigning '$lnode2' (type: '[nodeType $lnode2]') an automatic IP address"
if { $ipv4_addr2 == "" } { autoIPv4addr $lnode2 $ifname2 } if { $ipv4_addr2 == "" } { autoIPv4addr $lnode2 $ifname2 }
@ -872,7 +868,7 @@ proc newLink { lnode1 lnode2 } {
if { [nodeType $lnode2] != "pseudo" && if { [nodeType $lnode2] != "pseudo" &&
[nodeType $lnode1] != "wlan" && [nodeType $lnode1] != "wlan" &&
([[typemodel $lnode1].layer] == "NETWORK" && [nodeType $lnode1] != "OVS") } { ([[typemodel $lnode1].layer] == "NETWORK" && [nodeType $lnode1] != "OVS") } {
if { $ipv4_addr1 == "" && $do_auto_addressing } { if { $ipv4_addr1 == "" && $do_auto_addressing } {
autoIPv4addr $lnode1 $ifname1 autoIPv4addr $lnode1 $ifname1
} }
@ -884,16 +880,16 @@ proc newLink { lnode1 lnode2 } {
if { [nodeType $lnode1] != "pseudo" && if { [nodeType $lnode1] != "pseudo" &&
[nodeType $lnode1] != "wlan" && [nodeType $lnode1] != "wlan" &&
([[typemodel $lnode2].layer] == "NETWORK" && [nodeType $lnode2] != "OVS") } { ([[typemodel $lnode2].layer] == "NETWORK" && [nodeType $lnode2] != "OVS") } {
if { $ipv4_addr2 == "" && $do_auto_addressing } { if { $ipv4_addr2 == "" && $do_auto_addressing } {
autoIPv4addr $lnode2 $ifname2 autoIPv4addr $lnode2 $ifname2
} }
if { $ipv6_addr2 == "" && $do_auto_addressing } { if { $ipv6_addr2 == "" && $do_auto_addressing } {
autoIPv6addr $lnode2 $ifname2 autoIPv6addr $lnode2 $ifname2
} }
} }
# tunnel address based on its name # tunnel address based on its name
if { [nodeType $lnode1] == "tunnel" } { if { [nodeType $lnode1] == "tunnel" } {
set ipaddr "[getNodeName $lnode1]/24" set ipaddr "[getNodeName $lnode1]/24"
setIfcIPv4addr $lnode1 e0 $ipaddr setIfcIPv4addr $lnode1 e0 $ipaddr
@ -914,7 +910,7 @@ proc newLink { lnode1 lnode2 } {
# FUNCTION # FUNCTION
# Returns the link id of the link connecting the node's interface # Returns the link id of the link connecting the node's interface
# INPUTS # INPUTS
# * node_id -- node id # * node_id -- node id
# * ifc -- interface # * ifc -- interface
# RESULT # RESULT
# * link_id -- link id. # * link_id -- link id.
@ -1021,7 +1017,7 @@ proc updateLinkGuiAttr { link attr } {
} }
color { color {
setLinkColor $link $value setLinkColor $link $value
.c itemconfigure "link && $link" -fill [getLinkColor $link] .c itemconfigure "link && $link" -fill [getLinkColor $link]
} }
dash { dash {
.c itemconfigure "link && $link" -dash $value .c itemconfigure "link && $link" -dash $value

View file

@ -6,7 +6,7 @@
# shows the Two-node Tool # shows the Two-node Tool
proc popupTwoNodeDialog { } { proc popupTwoNodeDialog { } {
global twonodePID lastTwoNodeHop g_twoNodeSelect g_twoNodeSelectCallback global twonodePID lastTwoNodeHop g_twoNodeSelect g_twoNodeSelectCallback
markerOptions off markerOptions off
set wi .twonodetool set wi .twonodetool
catch {destroy $wi} catch {destroy $wi}
@ -61,7 +61,7 @@ proc popupTwoNodeDialog { } {
# buttons on the bottom # buttons on the bottom
frame $wi.butt -borderwidth 6 frame $wi.butt -borderwidth 6
button $wi.butt.run -text "Run" -command "runTwoNodeCommand $wi" button $wi.butt.run -text "Run" -command "runTwoNodeCommand $wi"
button $wi.butt.cancel -text "Clear" -command "clearTwoNodeDialog $wi 0" button $wi.butt.cancel -text "Clear" -command "clearTwoNodeDialog $wi 0"
button $wi.butt.close -text "Close" -command "clearTwoNodeDialog $wi 1" button $wi.butt.close -text "Close" -command "clearTwoNodeDialog $wi 1"
pack $wi.butt.run $wi.butt.cancel $wi.butt.close -side left pack $wi.butt.run $wi.butt.cancel $wi.butt.close -side left
@ -83,11 +83,7 @@ proc clearTwoNodeDialog { wi done} {
set emul [getEmulPlugin $node] set emul [getEmulPlugin $node]
set emulation_type [lindex $emul 1] set emulation_type [lindex $emul 1]
catch { catch {
if { $os == "FreeBSD" } { exec kill -9 $twonodePID 2> /dev/null
exec sudo kill -9 $twonodePID 2> /dev/null
} else {
exec kill -9 $twonodePID 2> /dev/null
}
} }
set twonodePID 0 set twonodePID 0
} }
@ -318,11 +314,11 @@ proc drawTwoNodeLine { node line type } {
# search for hops matching this nexthop address # search for hops matching this nexthop address
set hops [findNextHops $lastTwoNodeHop $nexthop ""] set hops [findNextHops $lastTwoNodeHop $nexthop ""]
if {[llength $hops] == 0} { if {[llength $hops] == 0} {
puts "Couldn't highlight next hop: $nexthop"; puts "Couldn't highlight next hop: $nexthop";
return return
} }
# highlight the path # highlight the path
set a $lastTwoNodeHop set a $lastTwoNodeHop
foreach b $hops { foreach b $hops {
highlightLink $a $b highlightLink $a $b
@ -372,7 +368,7 @@ proc nodeHasAddr { node addr } {
if { $nodeaddr == $addr } { if { $nodeaddr == $addr } {
return 1 return 1
} }
} }
return 0 return 0
} }
@ -429,7 +425,7 @@ proc clearLinkHighlights { } {
# Boeing: shows the Two-node Tool # Boeing: shows the Two-node Tool
proc popupRunDialog { } { proc popupRunDialog { } {
global node_list activetool systype global node_list activetool systype
set activetool select set activetool select
markerOptions off markerOptions off
set wi .runtool set wi .runtool
@ -489,7 +485,7 @@ proc popupRunDialog { } {
# buttons on the bottom # buttons on the bottom
frame $wi.butt -borderwidth 6 frame $wi.butt -borderwidth 6
button $wi.butt.run -text "Run" -command "runToolCommand $wi \"\"" button $wi.butt.run -text "Run" -command "runToolCommand $wi \"\""
button $wi.butt.close -text "Close" -command "destroy $wi" button $wi.butt.close -text "Close" -command "destroy $wi"
pack $wi.butt.run $wi.butt.close -side left pack $wi.butt.run $wi.butt.close -side left
pack $wi.butt -side bottom pack $wi.butt -side bottom
@ -504,7 +500,7 @@ proc runToolCommand { wi node } {
if { ![winfo exists $wi] } { return }; # user has closed window if { ![winfo exists $wi] } { return }; # user has closed window
# start running commands # start running commands
if { $node == "" } { if { $node == "" } {
$wi.results.text delete 1.0 end $wi.results.text delete 1.0 end
set selected [$wi.n.nodes.nodes curselection] set selected [$wi.n.nodes.nodes curselection]
if { [llength $selected] == 0 } { if { [llength $selected] == 0 } {
@ -518,8 +514,8 @@ proc runToolCommand { wi node } {
set next "" set next ""
set getnext 0 set getnext 0
foreach i [$wi.n.nodes.nodes curselection] { ;# find the next node foreach i [$wi.n.nodes.nodes curselection] { ;# find the next node
set n [lindex $node_list $i] set n [lindex $node_list $i]
if {$n == $node } { if {$n == $node } {
set getnext 1 set getnext 1
} elseif { $getnext == 1 } { } elseif { $getnext == 1 } {
@ -553,7 +549,7 @@ proc runToolCommand { wi node } {
# callback after receiving exec message response # callback after receiving exec message response
proc exec_runtool_callback { node execnum cmd result status } { proc exec_runtool_callback { node execnum cmd result status } {
set wi .runtool set wi .runtool
if { ![winfo exists $wi] } { return }; # user has closed window if { ![winfo exists $wi] } { return }; # user has closed window
$wi.results.text insert end "> $node > $cmd:\n" $wi.results.text insert end "> $node > $cmd:\n"

View file

@ -9,14 +9,13 @@ set g_imageFileTypes {{"images" {.gif}} {"images" {.jpg}} {"images" {.png}}
{"images" {.xbm}} {"All files" {*} }} {"images" {.xbm}} {"All files" {*} }}
global execMode global execMode
if { $execMode == "interactive"} { if { $execMode == "interactive"} {
if { [catch { package require Img }] } { if { [catch { package require Img }] } {
puts "warning: Tcl/Tk Img package not found" puts "warning: Tcl/Tk Img package not found"
puts " Thumbnails and other image types (JPG, PNG, etc.) will not be supported." puts " Thumbnails and other image types (JPG, PNG, etc.) will not be supported."
puts " Please install it with:" puts " Please install it with:"
puts " yum install tkimg (RedHat/Fedora)" puts " yum install tkimg (RedHat/Fedora)"
puts " sudo apt-get install libtk-img (Debian/Ubuntu)" puts " sudo apt-get install libtk-img (Debian/Ubuntu)\n"
puts " pkg_add -r libimg (FreeBSD)\n"
set g_imageFileTypes {{"images" {.gif}} {"All files" {*} }} set g_imageFileTypes {{"images" {.gif}} {"All files" {*} }}
} }
} }
@ -51,7 +50,7 @@ proc checkOS {} {
set machine [exec uname -m] set machine [exec uname -m]
set kernel [exec uname -v] set kernel [exec uname -v]
set x11 0 set x11 0
catch { set x11 [winfo server .c] } catch { set x11 [winfo server .c] }
set os_ident "$os_name $os_ver" set os_ident "$os_name $os_ver"
@ -203,7 +202,7 @@ proc upgradeNetworkConfigToServices { } {
puts "updating Quagga services on node $node" puts "updating Quagga services on node $node"
} ;# end quagga services } ;# end quagga services
# #
# convert static model to router # convert static model to router
# #
if { [getNodeModel $node] == "static" } { if { [getNodeModel $node] == "static" } {
setNodeModel $node "router" setNodeModel $node "router"
@ -223,7 +222,7 @@ proc upgradeNetworkConfigToServices { } {
setCustomConfig $node "service:UserDefined" "UserDefined" \ setCustomConfig $node "service:UserDefined" "UserDefined" \
$statvals 0 $statvals 0
setCustomConfig $node "service:UserDefined:$cfgname" $cfgname $cfg 0 setCustomConfig $node "service:UserDefined:$cfgname" $cfgname $cfg 0
set services [getNodeServices $node true] set services [getNodeServices $node true]
lappend services "UserDefined" lappend services "UserDefined"
setNodeServices $node $services setNodeServices $node $services
puts "adding user-defined static routing service on node $node" puts "adding user-defined static routing service on node $node"
@ -240,7 +239,7 @@ proc getCPUUsage { } {
} }
array set cpu {} array set cpu {}
while { [ gets $f line ] >= 0 } { while { [ gets $f line ] >= 0 } {
set cpun [lindex $line 0] set cpun [lindex $line 0]
set user [lindex $line 1]; set nice [lindex $line 2] set user [lindex $line 1]; set nice [lindex $line 2]
@ -264,14 +263,14 @@ proc getCPUUsage { } {
set usage_time [expr {($u-$lu) + ($n-$ln) + ($s-$ls)}] set usage_time [expr {($u-$lu) + ($n-$ln) + ($s-$ls)}]
set total_time [expr {$usage_time + ($i-$li)}] set total_time [expr {$usage_time + ($i-$li)}]
if { $total_time <= 0 } { if { $total_time <= 0 } {
set cpuusage "" ;# avoid div by zero set cpuusage "" ;# avoid div by zero
} else { } else {
set cpuusage [expr { 100 * $usage_time / $total_time }] set cpuusage [expr { 100 * $usage_time / $total_time }]
} }
lappend cpuusages $cpuusage lappend cpuusages $cpuusage
} }
return $cpuusages return $cpuusages
} }
# Node selection dialog display given message 'msg' with initial node selection # Node selection dialog display given message 'msg' with initial node selection
@ -294,7 +293,7 @@ proc popupSelectNodes { msg initsel callback } {
listbox $wi.nodes.fr.nodelist -width 40 \ listbox $wi.nodes.fr.nodelist -width 40 \
-listvariable node_list -yscrollcommand "$wi.nodes.fr.scroll set" \ -listvariable node_list -yscrollcommand "$wi.nodes.fr.scroll set" \
-activestyle dotbox -selectmode extended -activestyle dotbox -selectmode extended
scrollbar $wi.nodes.fr.scroll -command "$wi.nodes.fr.nodelist yview" scrollbar $wi.nodes.fr.scroll -command "$wi.nodes.fr.nodelist yview"
pack $wi.nodes.fr.nodelist -fill both -expand true -side left pack $wi.nodes.fr.nodelist -fill both -expand true -side left
pack $wi.nodes.fr.scroll -fill y -expand true -side left pack $wi.nodes.fr.scroll -fill y -expand true -side left
pack $wi.nodes.label $wi.nodes.fr -side top -padx 4 -pady 4 \ pack $wi.nodes.label $wi.nodes.fr -side top -padx 4 -pady 4 \
@ -352,7 +351,7 @@ proc popupRenumberNodes { } {
listbox $wi.nodes.left.fr.from -selectmode single -width 20 \ listbox $wi.nodes.left.fr.from -selectmode single -width 20 \
-listvariable node_list -yscrollcommand "$wi.nodes.left.fr.scroll set" \ -listvariable node_list -yscrollcommand "$wi.nodes.left.fr.scroll set" \
-activestyle dotbox -activestyle dotbox
scrollbar $wi.nodes.left.fr.scroll -command "$wi.nodes.left.fr.from yview" scrollbar $wi.nodes.left.fr.scroll -command "$wi.nodes.left.fr.from yview"
pack $wi.nodes.left.fr.from $wi.nodes.left.fr.scroll -fill y -side left pack $wi.nodes.left.fr.from $wi.nodes.left.fr.scroll -fill y -side left
pack $wi.nodes.left.label $wi.nodes.left.fr -side top -padx 4 -pady 4 \ pack $wi.nodes.left.label $wi.nodes.left.fr -side top -padx 4 -pady 4 \
-anchor w -anchor w
@ -487,24 +486,16 @@ proc addStaticRoutesToConfig { node cfg_ref } {
upvar 1 $cfg_ref cfg upvar 1 $cfg_ref cfg
foreach statrte [getStatIPv4routes $node] { foreach statrte [getStatIPv4routes $node] {
if {[lindex $systype 0] == "Linux" } { ;# Linux
set net [lindex [split $statrte] 0] set net [lindex [split $statrte] 0]
set gw [lindex [split $statrte] 1] set gw [lindex [split $statrte] 1]
lappend cfg "/sbin/ip -4 route add $net via $gw" lappend cfg "/sbin/ip -4 route add $net via $gw"
} else { ;# FreeBSD
lappend cfg "route -q add -inet $statrte"
}
} }
foreach statrte [getStatIPv6routes $node] { foreach statrte [getStatIPv6routes $node] {
if { [lindex $systype 0] == "Linux" } { ;# Linux
set net [lindex [split $statrte] 0] set net [lindex [split $statrte] 0]
set gw [lindex [split $statrte] 1] set gw [lindex [split $statrte] 1]
if { $net == "::/0" } { set net "default" } if { $net == "::/0" } { set net "default" }
lappend cfg "/sbin/ip -6 route add $net via $gw" lappend cfg "/sbin/ip -6 route add $net via $gw"
} else { ;# FreeBSD
lappend cfg "route -q add -inet6 $statrte"
}
} }
} }
@ -514,11 +505,7 @@ proc getServiceStartString { } {
setSystype setSystype
if { [lindex $systype 0] == "Linux" } { ;# Linux
return "/etc/init.d/core-daemon start" return "/etc/init.d/core-daemon start"
} else { ;# FreeBSD
return "/usr/local/etc/rc.d/core onestart"
}
} }
proc popupBuildHostsFile { } { proc popupBuildHostsFile { } {
@ -540,7 +527,7 @@ proc popupBuildHostsFile { } {
pack $wi.top.help -side top -fill both -expand true pack $wi.top.help -side top -fill both -expand true
pack $wi.top -padx 4 -pady 4 -side top pack $wi.top -padx 4 -pady 4 -side top
# text box # text box
frame $wi.mid frame $wi.mid
text $wi.mid.hosts -relief sunken -bd 2 \ text $wi.mid.hosts -relief sunken -bd 2 \
-yscrollcommand "$wi.mid.scroll set" -setgrid 1 -height 30 -undo 1 \ -yscrollcommand "$wi.mid.scroll set" -setgrid 1 -height 30 -undo 1 \
@ -585,7 +572,7 @@ proc popupBuildHostsFile { } {
set wi .buildhostsdialog set wi .buildhostsdialog
set hosts [string trim [$wi.mid.hosts get 0.0 end]] set hosts [string trim [$wi.mid.hosts get 0.0 end]]
set filename [$wi.fil.filename get] set filename [$wi.fil.filename get]
set fileId [open $filename a] set fileId [open $filename a]
puts $fileId $hosts puts $fileId $hosts
close $fileId close $fileId
destroy $wi destroy $wi
@ -707,7 +694,7 @@ proc addressConfigHelper { wi fam cmd } {
} }
} }
# set the default addresses for automatic allocation in the g_prefs array # set the default addresses for automatic allocation in the g_prefs array
# for the given address family # for the given address family
proc setDefaultAddrs { fam } { proc setDefaultAddrs { fam } {
global g_prefs global g_prefs
@ -737,8 +724,8 @@ proc popupMacAddressConfig { } {
frame $wi.top frame $wi.top
set helptext "MAC addresses are automatically assigned starting with\n" set helptext "MAC addresses are automatically assigned starting with\n"
set helptext "$helptext 00:00:00:aa:00:nn, where nn starts with the below" set helptext "$helptext 00:00:00:aa:00:nn, where nn starts with the below"
set helptext "$helptext value.\n You should change this value when tunneling" set helptext "$helptext value.\n You should change this value when tunneling"
set helptext "$helptext between \nemulations to prevent MAC address conflicts." set helptext "$helptext between \nemulations to prevent MAC address conflicts."
label $wi.top.help -text $helptext label $wi.top.help -text $helptext
pack $wi.top.help -side top -fill both -expand true pack $wi.top.help -side top -fill both -expand true
@ -863,7 +850,7 @@ proc _launchBrowser url {
# helper for registering a callback with a tk_optionMenu variable, when a user # helper for registering a callback with a tk_optionMenu variable, when a user
# clicks on the menu and changes the value; if the global variable var is # clicks on the menu and changes the value; if the global variable var is
# cleared, this callback is cancelled # cleared, this callback is cancelled
# NOTE: when closing the window that calls this, ensure that var is cleared # NOTE: when closing the window that calls this, ensure that var is cleared
proc tkOptionMenuCallback { ctl var cb args } { proc tkOptionMenuCallback { ctl var cb args } {
if { ![winfo exists $ctl] } { return } if { ![winfo exists $ctl] } { return }
@ -1094,7 +1081,7 @@ proc get_text_editor { want_default } {
if { $want_default } { if { $want_default } {
return "EDITOR" return "EDITOR"
} else { } else {
return $ed return $ed
} }
} }
# return the first installed editor from EDITORS global # return the first installed editor from EDITORS global
@ -1203,7 +1190,7 @@ proc delAddrsFromNodes { fam nodes } {
# fix for Tcl/Tk 8.5.8 and lower which doesn't have ttk::spinbox # fix for Tcl/Tk 8.5.8 and lower which doesn't have ttk::spinbox
# set spinbox [getspinbox] # set spinbox [getspinbox]
# $spinbox $var -justify right -width 10 ... # $spinbox $var -justify right -width 10 ...
# #
proc getspinbox {} { proc getspinbox {} {
if { [info command ttk::spinbox] == "" } { if { [info command ttk::spinbox] == "" } {
return spinbox return spinbox
@ -1308,7 +1295,7 @@ proc findButton { w } {
if { $first == "" } { if { $first == "" } {
$tree insert {} end -id none -values [list "" "" "" "no results found"] $tree insert {} end -id none -values [list "" "" "" "no results found"]
} else { } else {
$tree selection set $first $tree selection set $first
} }
. config -cursor left_ptr . config -cursor left_ptr

View file

@ -22,19 +22,19 @@ if {$vtysh == ""} {
# widget array: name, {config, init, periodic, move} # widget array: name, {config, init, periodic, move}
# #
array set widgets { array set widgets {
"Throughput" "Throughput"
{ widget_thru_config widget_thru_init widget_thru_periodic widget_thru_move } { widget_thru_config widget_thru_init widget_thru_periodic widget_thru_move }
"Adjacency" "Adjacency"
{ widget_adjacency_config widget_adjacency_init widget_adjacency_periodic widget_adjacency_move } { widget_adjacency_config widget_adjacency_init widget_adjacency_periodic widget_adjacency_move }
} }
# TODO: fix CPU Widget; it is disabled because Linux network namespaces and # TODO: fix CPU Widget; it is disabled because Linux network namespaces
# FreeBSD jails do not have a CPU usage reporting mechanism right now # do not have a CPU usage reporting mechanism right now
# "CPU" # "CPU"
# { widget_cpu_config widget_cpu_init widget_cpu_periodic widget_cpu_move } # { widget_cpu_config widget_cpu_init widget_cpu_periodic widget_cpu_move }
# Common Observer Widget definitions # Common Observer Widget definitions
set widgets_obs_quagga [subst { set widgets_obs_quagga [subst {
5 5
{{OSPFv2 neighbors} {$vtysh -c {show ip ospf neighbor}}} {{OSPFv2 neighbors} {$vtysh -c {show ip ospf neighbor}}}
6 6
@ -47,31 +47,6 @@ set widgets_obs_quagga [subst {
{{PIM neighbors} {$vtysh -c {show ip pim neighbor}}} {{PIM neighbors} {$vtysh -c {show ip pim neighbor}}}
}] }]
# Observer Widget definitions for FreeBSD
array set widgets_obs_bsd $widgets_obs_quagga
array set widgets_obs_bsd {
1
{ "processes" "ps ax" }
2
{ "ifconfig" "ifconfig" }
3
{ "IPv4 routes" "netstat -f inet -rn" }
4
{ "IPv6 routes" "netstat -f inet6 -rn" }
7
{ "IPv4 listening sockets" "sockstat -4l" }
8
{ "IPv6 listening sockets" "sockstat -6l" }
9
{ "IPv4 MFC entries" "ifmcstat -f inet" }
10
{ "IPv6 MFC entries" "ifmcstat -f inet6" }
11
{ "firewall rules" "ipfw -a list" }
12
{ "IPsec policies" "setkey -DP" }
}
# Observer Widget definitions for Linux # Observer Widget definitions for Linux
array set widgets_obs_linux $widgets_obs_quagga array set widgets_obs_linux $widgets_obs_quagga
array set widgets_obs_linux { array set widgets_obs_linux {
@ -104,17 +79,13 @@ set widget_loop_ID -1
# #
proc init_default_widgets_obs {} { proc init_default_widgets_obs {} {
global systype widgets widgets_obs widget_obs last_widgetObserveNode global systype widgets widgets_obs widget_obs last_widgetObserveNode
global widgets_obs_bsd widgets_obs_linux global widgets_obs_linux
setSystype setSystype
array unset widgets_obs array unset widgets_obs
if { [lindex $systype 0] == "Linux" } {
set arrayname widgets_obs_linux set arrayname widgets_obs_linux
# this works, but we will instead reset all indices: # this works, but we will instead reset all indices:
#array set widgets_obs [array get widgets_obs_linux] #array set widgets_obs [array get widgets_obs_linux]
} else {
set arrayname widgets_obs_bsd
}
# this resets the array indices to be 1, 2, 3, etc. # this resets the array indices to be 1, 2, 3, etc.
set i 1 set i 1
@ -142,7 +113,7 @@ proc init_widget_menu {} {
foreach w [array names widgets] { foreach w [array names widgets] {
global enable_$w global enable_$w
set enable_$w 0 set enable_$w 0
# note that a more modular way to break out submenus would be nice here # note that a more modular way to break out submenus would be nice here
if { $w == "Adjacency" } { if { $w == "Adjacency" } {
widget_adjacency_init_submenu .menubar.widgets widget_adjacency_init_submenu .menubar.widgets
continue continue
@ -374,9 +345,9 @@ proc configObsWidgets {} {
button $wi.c.c3.add -text "new" \ button $wi.c.c3.add -text "new" \
-command "configObsWidgetsHelper $wi 1" -command "configObsWidgetsHelper $wi 1"
button $wi.c.c3.mod -text "modify" \ button $wi.c.c3.mod -text "modify" \
-command "configObsWidgetsHelper $wi 2" -command "configObsWidgetsHelper $wi 2"
button $wi.c.c3.del -text "delete" \ button $wi.c.c3.del -text "delete" \
-command "configObsWidgetsHelper $wi 3" -command "configObsWidgetsHelper $wi 3"
pack $wi.c.c3.del $wi.c.c3.mod $wi.c.c3.add -side right pack $wi.c.c3.del $wi.c.c3.mod $wi.c.c3.add -side right
pack $wi.c.c3 -fill x -side top pack $wi.c.c3 -fill x -side top
@ -386,7 +357,7 @@ proc configObsWidgets {} {
frame $wi.s -borderwidth 4 frame $wi.s -borderwidth 4
listbox $wi.s.servers -selectmode single -width 50 \ listbox $wi.s.servers -selectmode single -width 50 \
-yscrollcommand "$wi.s.servers_scroll set" -exportselection 0 -yscrollcommand "$wi.s.servers_scroll set" -exportselection 0
scrollbar $wi.s.servers_scroll -command "$wi.s.servers yview" scrollbar $wi.s.servers_scroll -command "$wi.s.servers yview"
pack $wi.s.servers $wi.s.servers_scroll -fill y -side left pack $wi.s.servers $wi.s.servers_scroll -fill y -side left
pack $wi.s -fill x -side top pack $wi.s -fill x -side top
bind $wi.s.servers <<ListboxSelect>> "selectObsWidgetConf $wi" bind $wi.s.servers <<ListboxSelect>> "selectObsWidgetConf $wi"
@ -531,7 +502,7 @@ proc selectObsWidgetConf { wi } {
set selected [$wi.s.servers curselection] set selected [$wi.s.servers curselection]
# clear entries # clear entries
$wi.c.c.name delete 0 end $wi.c.c.name delete 0 end
$wi.c.c2.cmd delete 0 end $wi.c.c2.cmd delete 0 end
set w [$wi.s.servers get $selected] set w [$wi.s.servers get $selected]
@ -602,23 +573,18 @@ proc widget_thru_config {} {
checkbutton $wi.tlab.up \ checkbutton $wi.tlab.up \
-text "Include receptions" -variable thruConfig(up) -text "Include receptions" -variable thruConfig(up)
pack $wi.tlab.show_thru $wi.tlab.avg $wi.tlab.down \ pack $wi.tlab.show_thru $wi.tlab.avg $wi.tlab.down \
$wi.tlab.up -side top -anchor w -padx 4 $wi.tlab.up -side top -anchor w -padx 4
pack $wi.tlab -side top pack $wi.tlab -side top
frame $wi.msg -borderwidth 4 frame $wi.msg -borderwidth 4
global systype global systype
if { [lindex $systype 0] == "FreeBSD" } {
set lab1txt "Note: links with no impairments (bw, delay,\netc) "
set lab1txt "${lab1txt}will display 0.0 throughput"
} else {
set lab1txt "" set lab1txt ""
}
label $wi.msg.lab1 -text $lab1txt label $wi.msg.lab1 -text $lab1txt
pack $wi.msg.lab1 -side top -padx 4 -pady 4 pack $wi.msg.lab1 -side top -padx 4 -pady 4
pack $wi.msg -side top pack $wi.msg -side top
labelframe $wi.hi -padx 4 -pady 4 -text "Link highlighting" labelframe $wi.hi -padx 4 -pady 4 -text "Link highlighting"
# Threshold (set to zero to disable) # Threshold (set to zero to disable)
label $wi.hi.lab1 -text \ label $wi.hi.lab1 -text \
"Highlight link if throuhgput exceeds this " "Highlight link if throuhgput exceeds this "
@ -632,7 +598,7 @@ proc widget_thru_config {} {
scale $wi.hi.threshscale -from 0.0 -to 1000.0 -orient horizontal \ scale $wi.hi.threshscale -from 0.0 -to 1000.0 -orient horizontal \
-showvalue false -sliderrelief raised -variable thruConfig(thresh) -showvalue false -sliderrelief raised -variable thruConfig(thresh)
pack $wi.hi.threshscale -side top -fill x pack $wi.hi.threshscale -side top -fill x
frame $wi.hi.w frame $wi.hi.w
label $wi.hi.w.lab3 -text "Highlight link width:" label $wi.hi.w.lab3 -text "Highlight link width:"
spinbox $wi.hi.w.width -bg white -width 8 -textvariable thruConfig(width) \ spinbox $wi.hi.w.width -bg white -width 8 -textvariable thruConfig(width) \
@ -649,7 +615,7 @@ proc widget_thru_config {} {
pack $wi.hi.co.colbtn $wi.hi.co.color $wi.hi.co.lab1 \ pack $wi.hi.co.colbtn $wi.hi.co.color $wi.hi.co.lab1 \
-side right -padx 4 -pady 4 -side right -padx 4 -pady 4
pack $wi.hi.co -side top pack $wi.hi.co -side top
pack $wi.hi -side top pack $wi.hi -side top
# OK button at bottom # OK button at bottom
@ -748,7 +714,7 @@ proc ngctl_output_to_ifname { line } {
# Throughput widget periodic procedure # Throughput widget periodic procedure
# #
proc widget_thru_periodic { now } { proc widget_thru_periodic { now } {
global systype eid link_list global systype eid link_list
global link_thru_stats link_thru_avg_stats link_thru_last_time thruConfig global link_thru_stats link_thru_avg_stats link_thru_last_time thruConfig
global throughput_cache global throughput_cache
@ -759,7 +725,7 @@ proc widget_thru_periodic { now } {
set dt [expr { ($now - $link_thru_last_time)/1000.0 }] set dt [expr { ($now - $link_thru_last_time)/1000.0 }]
set link_thru_last_time $now set link_thru_last_time $now
if { $dt <= 0.0 } { return } if { $dt <= 0.0 } { return }
# keep wireless stats in an array # keep wireless stats in an array
array set wireless_stats {} array set wireless_stats {}
@ -820,7 +786,7 @@ proc widget_thru_periodic { now } {
set kbps [expr {$kbps + $kbps_down}] set kbps [expr {$kbps + $kbps_down}]
} }
#set kbps [expr {$kbps_down + $kbps_up}] #set kbps [expr {$kbps_down + $kbps_up}]
if { $thruConfig(avg) } { if { $thruConfig(avg) } {
if { ![info exists link_thru_avg_stats($key)] } { if { ![info exists link_thru_avg_stats($key)] } {
set link_thru_avg_stats($key) $kbps set link_thru_avg_stats($key) $kbps
@ -831,7 +797,7 @@ proc widget_thru_periodic { now } {
set kbps $s set kbps $s
} }
} }
set kbps_str [format "%.3f" $kbps] set kbps_str [format "%.3f" $kbps]
# wireless link - keep total of wireless throughput for this node # wireless link - keep total of wireless throughput for this node
# (supports membership to multiple wlans) # (supports membership to multiple wlans)
@ -855,14 +821,14 @@ proc widget_thru_periodic { now } {
} }
.c itemconfigure "link && $link" -width $width -fill $color .c itemconfigure "link && $link" -width $width -fill $color
} }
thruPlotUpdate .c $link $kbps thruPlotUpdate .c $link $kbps
}; # end foreach link }; # end foreach link
# after summing all wireless link bandwidths, go back and perform # after summing all wireless link bandwidths, go back and perform
# highlighting and label updating # highlighting and label updating
foreach node [array names wireless_stats] { foreach node [array names wireless_stats] {
set kbps_str [format "%.3f" $wireless_stats($node)] set kbps_str [format "%.3f" $wireless_stats($node)]
# erase any existing circles (otherwise we get duplicates) # erase any existing circles (otherwise we get duplicates)
.c delete -withtag "$node && rangecircles" .c delete -withtag "$node && rangecircles"
# wireless circle if exceeding threshold # wireless circle if exceeding threshold
@ -897,13 +863,13 @@ proc widget_thru_periodic { now } {
# helper to convert ng_pipe stats into upstream/downstream bytes # helper to convert ng_pipe stats into upstream/downstream bytes
proc getstats_bytes_netgraph { raw_input } { proc getstats_bytes_netgraph { raw_input } {
# Rec'd response "getstats" (1) from "e0_n0-n1:": # Rec'd response "getstats" (1) from "e0_n0-n1:":
# Args: { downstream={ FwdOctets=416 FwdFrames=6 } # Args: { downstream={ FwdOctets=416 FwdFrames=6 }
# upstream={ FwdOctets=416 FwdFrames=6 } } # upstream={ FwdOctets=416 FwdFrames=6 } }
set tmp [split $raw_input ":"] set tmp [split $raw_input ":"]
if { [llength $tmp] != 4 } { if { [llength $tmp] != 4 } {
return [list 0 0] return [list 0 0]
} }
set statline [lindex [lindex $tmp 3] 0] set statline [lindex [lindex $tmp 3] 0]
set down [lindex $statline 1] set down [lindex $statline 1]
set up [lindex $statline 5] set up [lindex $statline 5]
@ -952,8 +918,8 @@ proc getstats_bytes_proc { raw_input ifname } {
break break
} }
# match the ifname exactly # match the ifname exactly
} elseif { [string range $statline 0 $ifname_len] == "$ifname:" } { } elseif { [string range $statline 0 $ifname_len] == "$ifname:" } {
break break
} }
set statline "" set statline ""
} }
@ -964,8 +930,8 @@ proc getstats_bytes_proc { raw_input ifname } {
set stats [lindex $statline 1] set stats [lindex $statline 1]
set down_bytes [lindex $stats 0] set down_bytes [lindex $stats 0]
set up_bytes [lindex $stats 8] set up_bytes [lindex $stats 8]
if { $down_bytes == "" } { set down_bytes 0 } if { $down_bytes == "" } { set down_bytes 0 }
if { $up_bytes == "" } { set up_bytes 0 } if { $up_bytes == "" } { set up_bytes 0 }
@ -979,43 +945,43 @@ proc widget_thru_move { c node done } {
# Create a new throughput plot. # Create a new throughput plot.
proc thruPlot { c link x y height width isresize} { proc thruPlot { c link x y height width isresize} {
global widgets enable_Throughput thruPlotColor curPlotBgColor global widgets enable_Throughput thruPlotColor curPlotBgColor
global plot_list global plot_list
# if thruplot is called from resize, $link will hold full name # if thruplot is called from resize, $link will hold full name
if { $isresize == true } { if { $isresize == true } {
set g $link set g $link
# extract linkname from full path # extract linkname from full path
regexp {l(.*)thruplot} $g match sub1 regexp {l(.*)thruplot} $g match sub1
set link "l$sub1" set link "l$sub1"
} else { } else {
# if new thruplot is created create full name # if new thruplot is created create full name
set g "$c.${link}thruplot" set g "$c.${link}thruplot"
} }
# update plot_list # update plot_list
# Plot info to be stored : # Plot info to be stored :
# - canvas coords # - canvas coords
# - size (height, width) # - size (height, width)
# - color scheme # - color scheme
# - linkname # - linkname
# global plot variable that stores all plot info # global plot variable that stores all plot info
global ${link}thruplot global ${link}thruplot
# reset global variable # reset global variable
if {[info exists ${link}thruplot]} { unset ${link}thruplot} if {[info exists ${link}thruplot]} { unset ${link}thruplot}
set ${link}thruplot {} set ${link}thruplot {}
lappend ${link}thruplot "name $g" lappend ${link}thruplot "name $g"
lappend ${link}thruplot "height $height" lappend ${link}thruplot "height $height"
lappend ${link}thruplot "width $width" lappend ${link}thruplot "width $width"
lappend ${link}thruplot "x $x" lappend ${link}thruplot "x $x"
lappend ${link}thruplot "y $y" lappend ${link}thruplot "y $y"
# if not in color dict, add and set to default (blue)
# if not in color dict, add and set to default (blue)
if {[dict exists $thruPlotColor $g] == 0} { if {[dict exists $thruPlotColor $g] == 0} {
dict set thruPlotColor $g blue dict set thruPlotColor $g blue
set curPlotBgColor "#EEEEFF" set curPlotBgColor "#EEEEFF"
@ -1025,11 +991,11 @@ proc thruPlot { c link x y height width isresize} {
thruPlotSetScheme $scheme thruPlotSetScheme $scheme
lappend ${link}thruplot "color $scheme" lappend ${link}thruplot "color $scheme"
} }
# add plot to global plot_list # add plot to global plot_list
if {[lsearch $plot_list ${link}thruplot] eq -1} { if {[lsearch $plot_list ${link}thruplot] eq -1} {
lappend plot_list ${link}thruplot lappend plot_list ${link}thruplot
} }
# set global # set global
global $g global $g
@ -1040,7 +1006,7 @@ proc thruPlot { c link x y height width isresize} {
destroy $g # TODO: support multiple plots for the same link destroy $g # TODO: support multiple plots for the same link
} }
canvas $g -height $height -width $width -bg $curPlotBgColor canvas $g -height $height -width $width -bg $curPlotBgColor
$c create window $x $y -window $g -tags "thruplot $g" $c create window $x $y -window $g -tags "thruplot $g"
# set link interface title # set link interface title
@ -1049,21 +1015,21 @@ proc thruPlot { c link x y height width isresize} {
set if1 [ifcByPeer $lnode1 $lnode2] set if1 [ifcByPeer $lnode1 $lnode2]
set if2 [ifcByPeer $lnode2 $lnode1] set if2 [ifcByPeer $lnode2 $lnode1]
# if too narrow, bring title down # if too narrow, bring title down
if {$width < 220} { if {$width < 220} {
$g create text $width 20 -anchor ne -text "$if1@$lnode1 - $if2@$lnode2" $g create text $width 20 -anchor ne -text "$if1@$lnode1 - $if2@$lnode2"
} else { } else {
$g create text $width 0 -anchor ne -text "$if1@$lnode1 - $if2@$lnode2" $g create text $width 0 -anchor ne -text "$if1@$lnode1 - $if2@$lnode2"
} }
# bind items # bind items
bind $g <1> "thruPlotClick $c $g %x %y none" bind $g <1> "thruPlotClick $c $g %x %y none"
bind $g <B1-Motion> "thruPlotHandleB1Motion $c $g %x %y start" bind $g <B1-Motion> "thruPlotHandleB1Motion $c $g %x %y start"
bind $g <3> "thruPlotPopup $g %x %y" bind $g <3> "thruPlotPopup $g %x %y"
#DYL trying to update cursor look #DYL trying to update cursor look
bind $g <Motion> "selectmarkEnter $g %x %y" bind $g <Motion> "selectmarkEnter $g %x %y"
bind $g <Any-Leave> "selectmarkLeave $c %x %y" bind $g <Any-Leave> "selectmarkLeave $c %x %y"
bind $g <B1-ButtonRelease> "thruPlotHandleRelease $c $g %x %y done" bind $g <B1-ButtonRelease> "thruPlotHandleRelease $c $g %x %y done"
#TODO when we are inside the thruplot, the graph hides the cursor #TODO when we are inside the thruplot, the graph hides the cursor
@ -1085,27 +1051,27 @@ proc thruPlotPopup {g xclick yclick } {
.button3menu delete 0 end .button3menu delete 0 end
.button3menu.color delete 0 end .button3menu.color delete 0 end
.button3menu add cascade -label "Set Color" -menu .button3menu.color .button3menu add cascade -label "Set Color" -menu .button3menu.color
# color red
.button3menu.color add command -label "Red" -command "setThruPlotColor $g red"
# color blue
.button3menu.color add command -label "Green" -command "setThruPlotColor $g green"
# color green # color red
.button3menu.color add command -label "Red" -command "setThruPlotColor $g red"
# color blue
.button3menu.color add command -label "Green" -command "setThruPlotColor $g green"
# color green
.button3menu.color add command -label "Blue" -command "setThruPlotColor $g blue" .button3menu.color add command -label "Blue" -command "setThruPlotColor $g blue"
# delete # delete
.button3menu add command -label "Delete" -command "deletePlot $g" .button3menu add command -label "Delete" -command "deletePlot $g"
set x [winfo pointerx .] set x [winfo pointerx .]
set y [winfo pointery .] set y [winfo pointery .]
tk_popup .button3menu $x $y tk_popup .button3menu $x $y
} }
# remove thruplot # remove thruplot
proc deletePlot { g } { proc deletePlot { g } {
global plot_list global plot_list
regexp {.c.(.*thruplot)} $g match plotname regexp {.c.(.*thruplot)} $g match plotname
@ -1119,15 +1085,15 @@ proc deletePlot { g } {
# Mouse click on a throughput plot. # Mouse click on a throughput plot.
# check to see if resize # check to see if resize
proc thruPlotClick { c g x y modifier } { proc thruPlotClick { c g x y modifier } {
global thruplotResize cursorToResizemode resizemode resizeobj thruPlotDragStart thruPlotCur global thruplotResize cursorToResizemode resizemode resizeobj thruPlotDragStart thruPlotCur
set cursorMode [$c cget -cursor] set cursorMode [$c cget -cursor]
# check if resizeMode # check if resizeMode
if {$cursorMode != "left_ptr" && $cursorMode != "crosshair"} { if {$cursorMode != "left_ptr" && $cursorMode != "crosshair"} {
global oldX1 oldY1 oldX2 oldY2 global oldX1 oldY1 oldX2 oldY2
# save old top left and bottom right points # save old top left and bottom right points
set bbox [$c bbox $g] set bbox [$c bbox $g]
set oldX1 [lindex $bbox 0] set oldX1 [lindex $bbox 0]
set oldY1 [lindex $bbox 1] set oldY1 [lindex $bbox 1]
@ -1135,28 +1101,28 @@ proc thruPlotClick { c g x y modifier } {
set oldY2 [lindex $bbox 3] set oldY2 [lindex $bbox 3]
# set resizeobj and resize mode # set resizeobj and resize mode
set resizeobj $g set resizeobj $g
set resizemode [dict get $cursorToResizemode $cursorMode] set resizemode [dict get $cursorToResizemode $cursorMode]
set thruplotResize true set thruplotResize true
} else { } else {
# update cursor to drag (crosshair) # update cursor to drag (crosshair)
$c configure -cursor crosshair $c configure -cursor crosshair
set thruPlotDragStart true set thruPlotDragStart true
set thruPlotCur $g set thruPlotCur $g
} }
} }
# Must handle either a resize or a drag # Must handle either a resize or a drag
# The plot canvas gets the B1-Motion event, not the parent canvas # The plot canvas gets the B1-Motion event, not the parent canvas
proc thruPlotHandleB1Motion {c g x y what} { proc thruPlotHandleB1Motion {c g x y what} {
global thruplotResize resizemode resizeobj global thruplotResize resizemode resizeobj
set cursorMode [$c cget -cursor] set cursorMode [$c cget -cursor]
# check if drag (center is clicked) # check if drag (center is clicked)
if {($cursorMode == "left_ptr" || $cursorMode == "crosshair") && $thruplotResize == false} { if {($cursorMode == "left_ptr" || $cursorMode == "crosshair") && $thruplotResize == false} {
thruPlotDrag $c $g $x $y $what false thruPlotDrag $c $g $x $y $what false
} else { } else {
# resize was clicked # resize was clicked
} }
} }
@ -1168,30 +1134,30 @@ proc thruPlotHandleRelease { c g x y what} {
thruPlotDrag $c $g $x $y $what false thruPlotDrag $c $g $x $y $what false
} else { } else {
thruPlotRescale $c $g $x $y thruPlotRescale $c $g $x $y
} }
} }
# redraw thruplot # redraw thruplot
# x y show coords relative to top left corner of thruplot # x y show coords relative to top left corner of thruplot
proc thruPlotRescale { c g x y } { proc thruPlotRescale { c g x y } {
global thruplotResize resizemode oldX1 oldY1 oldX2 oldY2 global thruplotResize resizemode oldX1 oldY1 oldX2 oldY2
# resize based on resize mode # resize based on resize mode
switch $resizemode { switch $resizemode {
ld { ld {
# if the left bot corner is clicked just look at new x set new height # if the left bot corner is clicked just look at new x set new height
lassign [calcDimensions [expr {$oldX1 + $x}] $oldY1 $oldX2 [expr {$oldY1 + $y}]] cx cy h w lassign [calcDimensions [expr {$oldX1 + $x}] $oldY1 $oldX2 [expr {$oldY1 + $y}]] cx cy h w
thruPlot $c $g $cx $cy $h $w true thruPlot $c $g $cx $cy $h $w true
} }
ru { ru {
# if the right top corner is clicked just look at new x set new heigth # if the right top corner is clicked just look at new x set new heigth
lassign [calcDimensions $oldX1 [expr {$oldY1 + $y}] [expr {$oldX1 + $x}] $oldY2] cx cy h w lassign [calcDimensions $oldX1 [expr {$oldY1 + $y}] [expr {$oldX1 + $x}] $oldY2] cx cy h w
thruPlot $c $g $cx $cy $h $w true thruPlot $c $g $cx $cy $h $w true
} }
rd { rd {
# if the right bottom corner clicked # if the right bottom corner clicked
lassign [calcDimensions $oldX1 $oldY1 [expr {$oldX1 + $x}] [expr {$oldY1 + $y}]] cx cy h w lassign [calcDimensions $oldX1 $oldY1 [expr {$oldX1 + $x}] [expr {$oldY1 + $y}]] cx cy h w
thruPlot $c $g $cx $cy $h $w true thruPlot $c $g $cx $cy $h $w true
} }
lu { lu {
# if the left bottom corner clicked # if the left bottom corner clicked
@ -1205,44 +1171,44 @@ proc thruPlotRescale { c g x y } {
} }
l { l {
# if the left side is clicked just look at new x # if the left side is clicked just look at new x
lassign [calcDimensions [expr {$oldX1 + $x}] $oldY1 $oldX2 $oldY2] cx cy h w lassign [calcDimensions [expr {$oldX1 + $x}] $oldY1 $oldX2 $oldY2] cx cy h w
thruPlot $c $g $cx $cy $h $w true thruPlot $c $g $cx $cy $h $w true
} }
u { u {
# if the top side is click just look at new y # if the top side is click just look at new y
lassign [calcDimensions $oldX1 [expr {$oldY1 + $y}] $oldX2 $oldY2] cx cy h w lassign [calcDimensions $oldX1 [expr {$oldY1 + $y}] $oldX2 $oldY2] cx cy h w
thruPlot $c $g $cx $cy $h $w true thruPlot $c $g $cx $cy $h $w true
} }
d { d {
# if the top side is click just look at new y # if the top side is click just look at new y
lassign [calcDimensions $oldX1 $oldY1 $oldX2 [expr {$oldY1 + $y}]] cx cy h w lassign [calcDimensions $oldX1 $oldY1 $oldX2 [expr {$oldY1 + $y}]] cx cy h w
thruPlot $c $g $cx $cy $h $w true thruPlot $c $g $cx $cy $h $w true
} }
default { default {
puts "ERROR: should not come here. resize mode is invalid." puts "ERROR: should not come here. resize mode is invalid."
} }
} }
# rescale is done reset rescale global variables # rescale is done reset rescale global variables
set cursor left_ptr set cursor left_ptr
set thruplotResize false set thruplotResize false
set resizemode false set resizemode false
} }
# Calculate center, height, width based on top left and bot right corners # Calculate center, height, width based on top left and bot right corners
proc calcDimensions { x1 y1 x2 y2 } { proc calcDimensions { x1 y1 x2 y2 } {
set h [expr {$y2 - $y1}] set h [expr {$y2 - $y1}]
set w [expr {$x2 - $x1}] set w [expr {$x2 - $x1}]
# enforce min size # enforce min size
if {$h < 100} { if {$h < 100} {
set h 100 set h 100
} }
if {$w < 100} { if {$w < 100} {
set w 100 set w 100
} }
list [expr {$x1 + ($w/2)}] [expr {$y1 + ($h/2)}] $h $w list [expr {$x1 + ($w/2)}] [expr {$y1 + ($h/2)}] $h $w
} }
# Mouse drag a throughput plot. # Mouse drag a throughput plot.
@ -1250,67 +1216,67 @@ proc thruPlotDrag { c g x y what fromCanvas} {
global thruPlotDragStart thruPlotCur global thruPlotDragStart thruPlotCur
global plot_list global plot_list
set pad 60 set pad 60
set maxjump 500 set maxjump 500
# this fixes a bug when thruplot is off screen # this fixes a bug when thruplot is off screen
if {$fromCanvas == true} { if {$fromCanvas == true} {
#puts "handling from canvas" #puts "handling from canvas"
$c coords $thruPlotCur [expr {$x - $pad}] [expr {$y- $pad}] $c coords $thruPlotCur [expr {$x - $pad}] [expr {$y- $pad}]
return return
} }
if {$thruPlotDragStart == false} { if {$thruPlotDragStart == false} {
if { [expr abs($x)] > $maxjump || [expr abs($y)] > $maxjump} { if { [expr abs($x)] > $maxjump || [expr abs($y)] > $maxjump} {
puts "ERROR can not drag too far at one time" puts "ERROR can not drag too far at one time"
return return
} }
} else { } else {
set curx [lindex [$c coords $g] 0] set curx [lindex [$c coords $g] 0]
set cury [lindex [$c coords $g] 1] set cury [lindex [$c coords $g] 1]
# perform the actual drag # perform the actual drag
set newx [expr {$x - $pad + $curx}] set newx [expr {$x - $pad + $curx}]
set newy [expr {$y- $pad + $cury}] set newy [expr {$y- $pad + $cury}]
$c coords $thruPlotCur $newx $newy $c coords $thruPlotCur $newx $newy
# save new coords DYL # save new coords DYL
regexp {.c.(l.*thruplot)} $g match name regexp {.c.(l.*thruplot)} $g match name
# global ${name} # global ${name}
# find and replace x coord # find and replace x coord
updatePlotAttr ${name} "x" $newx updatePlotAttr ${name} "x" $newx
updatePlotAttr ${name} "y" $newy updatePlotAttr ${name} "y" $newy
set thruPlotDragStart dragging set thruPlotDragStart dragging
} }
} }
proc redrawAllThruplots {} { proc redrawAllThruplots {} {
global plot_list global plot_list
foreach tp $plot_list { foreach tp $plot_list {
# extract the following properties from the thruplot : # extract the following properties from the thruplot :
# full path # full path
# height, width # height, width
# x,y coords, # x,y coords,
# color scheme # color scheme
set fp [getPlotAttr $tp name] set fp [getPlotAttr $tp name]
set height [getPlotAttr $tp height] set height [getPlotAttr $tp height]
set width [getPlotAttr $tp width] set width [getPlotAttr $tp width]
set x [getPlotAttr $tp x] set x [getPlotAttr $tp x]
set y [getPlotAttr $tp y] set y [getPlotAttr $tp y]
set color [getPlotAttr $tp color] set color [getPlotAttr $tp color]
thruPlot .c $fp $x $y $height $width true thruPlot .c $fp $x $y $height $width true
setThruPlotColor $fp $color setThruPlotColor $fp $color
} }
} }
# this will update an attribute of the global thruplot variable # this will update an attribute of the global thruplot variable
proc updatePlotAttr { plot attr val } { proc updatePlotAttr { plot attr val } {
# puts "updating $attr of ${plot} to $val" # puts "updating $attr of ${plot} to $val"
global ${plot} global ${plot}
# find and replace attribute # find and replace attribute
set i [lsearch [set ${plot}] "$attr *"] set i [lsearch [set ${plot}] "$attr *"]
# puts " found at $i" # puts " found at $i"
if { $i >= 0 } { if { $i >= 0 } {
@ -1320,7 +1286,7 @@ proc updatePlotAttr { plot attr val } {
} }
} }
# this will return an attribute from the plotlist # this will return an attribute from the plotlist
proc getPlotAttr {plot attr} { proc getPlotAttr {plot attr} {
global ${plot} global ${plot}
@ -1345,7 +1311,7 @@ proc setThruPlotColor { g color} {
# set global variables that determine color scheme # set global variables that determine color scheme
thruPlotSetScheme $color thruPlotSetScheme $color
# update old data # update old data
$g itemconfigure "filler" -fill $curPlotFillColor $g itemconfigure "filler" -fill $curPlotFillColor
$g itemconfigure "line" -fill $curPlotLineColor $g itemconfigure "line" -fill $curPlotLineColor
$g configure -bg $curPlotBgColor $g configure -bg $curPlotBgColor
@ -1372,15 +1338,15 @@ proc thruPlotSetScheme { color } {
set curPlotBgColor "#eeffee" set curPlotBgColor "#eeffee"
} }
default { default {
puts "ERROR: invalid plot color '$color'" puts "ERROR: invalid plot color '$color'"
} }
} }
} }
# update a throughput plot with a new data point # update a throughput plot with a new data point
proc thruPlotUpdate { c link kbps } { proc thruPlotUpdate { c link kbps } {
set g "$c.${link}thruplot" set g "$c.${link}thruplot"
global $g curPlotLineColor curPlotFillColor curPlotBgColor thruPlotColor thruPlotMaxKBPS global $g curPlotLineColor curPlotFillColor curPlotBgColor thruPlotColor thruPlotMaxKBPS
# Check if window exists # Check if window exists
if { ![winfo exists $g] } { if { ![winfo exists $g] } {
@ -1389,10 +1355,10 @@ proc thruPlotUpdate { c link kbps } {
# lookup scheme for thruplot and set scheme # lookup scheme for thruplot and set scheme
set scheme [dict get $thruPlotColor $g] set scheme [dict get $thruPlotColor $g]
thruPlotSetScheme $scheme thruPlotSetScheme $scheme
# set bg to scheme # set bg to scheme
$g configure -bg $curPlotBgColor $g configure -bg $curPlotBgColor
set maxx [$g cget -width] set maxx [$g cget -width]
set maxy [$g cget -height] set maxy [$g cget -height]
set yscale [thruPlotAutoScale $g $kbps] set yscale [thruPlotAutoScale $g $kbps]
@ -1400,7 +1366,7 @@ proc thruPlotUpdate { c link kbps } {
# shift graph to the left by dt pixels # shift graph to the left by dt pixels
set dt 5.0 set dt 5.0
$g move "data" -$dt 0.0 $g move "data" -$dt 0.0
thruPlotDeleteOldData $g $dt thruPlotDeleteOldData $g $dt
set last [$g find withtag "data && last"] set last [$g find withtag "data && last"]
@ -1416,8 +1382,8 @@ proc thruPlotUpdate { c link kbps } {
$g create polygon $x1 $y1 $x2 $y2 $x2 $maxy $x1 $maxy \ $g create polygon $x1 $y1 $x2 $y2 $x2 $maxy $x1 $maxy \
-tags "data filler" -fill $curPlotFillColor -width 2 -tags "data filler" -fill $curPlotFillColor -width 2
$g create line $x1 $y1 $x2 $y2 -tags "data last line" -fill $curPlotLineColor $g create line $x1 $y1 $x2 $y2 -tags "data last line" -fill $curPlotLineColor
} }
# return the existing y-value scale; if the given value is off the scale, # return the existing y-value scale; if the given value is off the scale,
@ -1426,21 +1392,21 @@ proc thruPlotAutoScale { g val } {
set yscale [lindex [$g itemcget "ticks && scalemax" -text] 0] set yscale [lindex [$g itemcget "ticks && scalemax" -text] 0]
global thruPlotMaxKBPS global thruPlotMaxKBPS
# update global max # update global max
if { $val > $thruPlotMaxKBPS} { if { $val > $thruPlotMaxKBPS} {
set thruPlotMaxKBPS $val set thruPlotMaxKBPS $val
} else { } else {
set val $thruPlotMaxKBPS set val $thruPlotMaxKBPS
} }
# default # default
if { $yscale == "" || $yscale < 1.0 } { if { $yscale == "" || $yscale < 1.0 } {
set yscale 10.0 set yscale 10.0
} }
if { $val < $yscale } { if { $val < $yscale } {
return $yscale ;# value within bounds of existing scale return $yscale ;# value within bounds of existing scale
} }
set maxy [$g cget -height] set maxy [$g cget -height]
set newyscale [expr {ceil($val) + 5.0}] set newyscale [expr {ceil($val) + 5.0}]
@ -1519,7 +1485,7 @@ proc thruPlotDrawScale { g max } {
proc thruPlotDeleteOldData { g dt } { proc thruPlotDeleteOldData { g dt } {
foreach i [$g find withtag "data"] { foreach i [$g find withtag "data"] {
if { [lindex [$g coords $i] 0] < [expr { -2.0 * $dt }] } { if { [lindex [$g coords $i] 0] < [expr { -2.0 * $dt }] } {
$g delete $i $g delete $i
} }
} }
} }
@ -1571,7 +1537,7 @@ proc widget_cpu_config {} {
labelframe $wi.hi -padx 4 -pady 4 -text "Node highlighting" labelframe $wi.hi -padx 4 -pady 4 -text "Node highlighting"
# Threshold (set to zero to disable) # Threshold (set to zero to disable)
label $wi.hi.lab1 -text "Highlight node if CPU usage exceeds this " label $wi.hi.lab1 -text "Highlight node if CPU usage exceeds this "
pack $wi.hi.lab1 -side top -anchor w pack $wi.hi.lab1 -side top -anchor w
@ -1581,7 +1547,7 @@ proc widget_cpu_config {} {
label $wi.hi.t.lab2 -text "% CPU" label $wi.hi.t.lab2 -text "% CPU"
pack $wi.hi.t.lab2 $wi.hi.t.thresh $wi.hi.t.lab1 -side right -padx 4 -pady 4 pack $wi.hi.t.lab2 $wi.hi.t.thresh $wi.hi.t.lab1 -side right -padx 4 -pady 4
pack $wi.hi.lab1 $wi.hi.t -side top pack $wi.hi.lab1 $wi.hi.t -side top
# Highlight color/width # Highlight color/width
frame $wi.hi.w frame $wi.hi.w
label $wi.hi.w.lab3 -text "radius:" label $wi.hi.w.lab3 -text "radius:"
@ -1597,7 +1563,7 @@ proc widget_cpu_config {} {
pack $wi.hi.w.colbtn $wi.hi.w.color $wi.hi.w.lab1 \ pack $wi.hi.w.colbtn $wi.hi.w.color $wi.hi.w.lab1 \
-side right -padx 4 -pady 4 -side right -padx 4 -pady 4
pack $wi.hi.w -side top pack $wi.hi.w -side top
pack $wi.hi -side top -fill x pack $wi.hi -side top -fill x
# OK button at bottom # OK button at bottom
@ -1642,13 +1608,8 @@ proc widget_cpu_init {command} {
# #
proc widget_cpu_periodic { now } { proc widget_cpu_periodic { now } {
global systype global systype
if { [lindex $systype 0] == "FreeBSD" } {
widget_cpu_periodic_vimage $now
} else {
puts "warning: the CPU widget is not functional for this platform yet" puts "warning: the CPU widget is not functional for this platform yet"
return return
}
} }
proc widget_cpu_periodic_vimage { now } { proc widget_cpu_periodic_vimage { now } {
@ -1664,10 +1625,10 @@ proc widget_cpu_periodic_vimage { now } {
set newtext [format "%.2f %%" $cpustats($eid\_$node)] set newtext [format "%.2f %%" $cpustats($eid\_$node)]
set coords [getCPUcoords $node] set coords [getCPUcoords $node]
set x [lindex $coords 0] set x [lindex $coords 0]
set y [lindex $coords 1] set y [lindex $coords 1]
set basex [lindex $coords 2] set basex [lindex $coords 2]
set basey [lindex $coords 3] set basey [lindex $coords 3]
set existing [.c find withtag "cpulabel && $node"] set existing [.c find withtag "cpulabel && $node"]
if { [llength $existing] == 0 } { ;# create new label if { [llength $existing] == 0 } { ;# create new label
@ -1678,7 +1639,7 @@ proc widget_cpu_periodic_vimage { now } {
.c itemconfigure $cpulabel -text $newtext .c itemconfigure $cpulabel -text $newtext
} }
.c raise $cpulabel .c raise $cpulabel
# perform highlighting # perform highlighting
set existing [.c find withtag "cpuhi && $node"] set existing [.c find withtag "cpuhi && $node"]
if { $cpustats($eid\_$node) >= $cpuConfig(thresh) } { if { $cpustats($eid\_$node) >= $cpuConfig(thresh) } {
if { [llength $existing] == 0 } { if { [llength $existing] == 0 } {
@ -1692,7 +1653,7 @@ proc widget_cpu_periodic_vimage { now } {
#.c raise "link && $node" #.c raise "link && $node"
.c raise "node && $node" .c raise "node && $node"
} }
} elseif { [llength $existing] > 0 } { } elseif { [llength $existing] > 0 } {
.c delete $existing .c delete $existing
} }
@ -1726,7 +1687,7 @@ proc getstats_cpu_vimage { raw_input} {
if { $numlines <= 4 } { if { $numlines <= 4 } {
return [list 0 0] return [list 0 0]
} }
# add node_name/cpu to a list # add node_name/cpu to a list
set ret {} set ret {}
set i 0 set i 0
@ -1756,7 +1717,7 @@ proc getstats_cpu_vestat { } {
global cpu_vestat_history; # remember previous jiffies global cpu_vestat_history; # remember previous jiffies
set Hertz 100.0; # from <asm/param.h>, varies per architecture set Hertz 100.0; # from <asm/param.h>, varies per architecture
# read /proc/vz/vestat # read /proc/vz/vestat
if { [catch {set f [open "/proc/vz/vestat" r]} e] } { if { [catch {set f [open "/proc/vz/vestat" r]} e] } {
puts "error opening /proc/vz/vestat: $e" puts "error opening /proc/vz/vestat: $e"
return return
@ -1784,8 +1745,8 @@ proc getstats_cpu_vestat { } {
array set cpu_vestat_history [list uptime $uptime_now] array set cpu_vestat_history [list uptime $uptime_now]
set elapsed [expr {$uptime_now - $uptime_old}] set elapsed [expr {$uptime_now - $uptime_old}]
if { $elapsed == 0.0 } { set elapsed 1.0 }; # don't divide by zero if { $elapsed == 0.0 } { set elapsed 1.0 }; # don't divide by zero
# add node_name/cpu to a list # add node_name/cpu to a list
set ret {} set ret {}
for { set i 0 } { $i < [llength $lines] } { incr i } { for { set i 0 } { $i < [llength $lines] } { incr i } {
@ -1943,7 +1904,7 @@ proc get_router_id {node} {
} }
} }
if {[lsearch [getNodeServices $node true] "OLSR"] != -1 } { if {[lsearch [getNodeServices $node true] "OLSR"] != -1 } {
set sock [lindex [getEmulPlugin $node] 2] set sock [lindex [getEmulPlugin $node] 2]
set exec_num [newExecCallbackRequest adjacencyrouterid] set exec_num [newExecCallbackRequest adjacencyrouterid]
set name [getNodeName $node] set name [getNodeName $node]
@ -2008,7 +1969,7 @@ proc widget_adjacency_init {command} {
set enable_Adjacency_OSPFv3 0 set enable_Adjacency_OSPFv3 0
set enable_Adjacency_OLSR 0 set enable_Adjacency_OLSR 0
set adjacency_config(proto) "OLSRv2_proto" set adjacency_config(proto) "OLSRv2_proto"
} }
} }
# Initialize # Initialize
@ -2017,7 +1978,7 @@ proc widget_adjacency_init {command} {
foreach node $node_list { ;# save router-id node pairs for later lookup foreach node $node_list { ;# save router-id node pairs for later lookup
if { [nodeType $node] != "router" } { continue } if { [nodeType $node] != "router" } { continue }
if {[lsearch [getNodeServices $node true] "zebra"] < 0 && if {[lsearch [getNodeServices $node true] "zebra"] < 0 &&
[lsearch [getNodeServices $node true] "OLSR"] < 0 && [lsearch [getNodeServices $node true] "OLSR"] < 0 &&
[lsearch [getNodeServices $node true] "OLSRv2"] < 0} { [lsearch [getNodeServices $node true] "OLSRv2"] < 0} {
continue continue
} }
@ -2107,16 +2068,16 @@ proc exec_adjacency_callback { node execnum cmd result status } {
global g_api_exec_num global g_api_exec_num
set changed 0 set changed 0
set c .c set c .c
set proto $adjacency_config(proto) set proto $adjacency_config(proto)
array set colors $adjacency_config(colors) array set colors $adjacency_config(colors)
if { $adjacency_config(offset) } { set o 5 } else { set o 0 } if { $adjacency_config(offset) } { set o 5 } else { set o 0 }
$c addtag adjdelete withtag "adjline && $node" ;# flag del all adjlines $c addtag adjdelete withtag "adjline && $node" ;# flag del all adjlines
set adjs [getadj_from_neighbors $result $proto] set adjs [getadj_from_neighbors $result $proto]
foreach adj $adjs { foreach adj $adjs {
set peer [lindex $adj 0] set peer [lindex $adj 0]
set line [$c find withtag "adjline && $node && $peer"] set line [$c find withtag "adjline && $node && $peer"]
@ -2193,7 +2154,7 @@ proc getadj_from_neighbors { raw_input proto } {
"LOST" { set state "Down" } "LOST" { set state "Down" }
"MPR" { set state "Full" } "MPR" { set state "Full" }
"PENDING" { set state "Init" } "PENDING" { set state "Init" }
"INVALID" { set state "Down" } "INVALID" { set state "Down" }
} }
lappend ret [list $rtrid $state] lappend ret [list $rtrid $state]
} }
@ -2205,7 +2166,7 @@ proc getadj_from_neighbors { raw_input proto } {
#10.0.0.2 1 00:00:06 Init/PointToPoint 00:00:00 eth0[PointToP #10.0.0.2 1 00:00:06 Init/PointToPoint 00:00:00 eth0[PointToP
#10.0.0.2 1 00:00:06 Twoway/PointToPoint 00:00:00 eth0[PointToP #10.0.0.2 1 00:00:06 Twoway/PointToPoint 00:00:00 eth0[PointToP
#10.0.0.2 1 00:00:06 Full/PointToPoint 00:00:38 eth0[PointToP #10.0.0.2 1 00:00:06 Full/PointToPoint 00:00:38 eth0[PointToP
#10.0.7.2 1 Full/Backup 37.240s 10.0.0.2 eth0:10.0.0.1 #10.0.7.2 1 Full/Backup 37.240s 10.0.0.2 eth0:10.0.0.1
foreach line [split $raw_input "\n"] { foreach line [split $raw_input "\n"] {
set rtrid [string trim [string range $line 0 14]] set rtrid [string trim [string range $line 0 14]]
if { $rtrid == "Neighbor ID" } { continue } if { $rtrid == "Neighbor ID" } { continue }
@ -2284,17 +2245,17 @@ proc widget_adjacency_init_submenu { m } {
set enable_Adjacency_OSPFv2 0 set enable_Adjacency_OSPFv2 0
$m.adj add checkbutton -label "OSPFv2" -variable enable_Adjacency_OSPFv2 \ $m.adj add checkbutton -label "OSPFv2" -variable enable_Adjacency_OSPFv2 \
-command "[lindex $widgets(Adjacency) 1] menu2" -command "[lindex $widgets(Adjacency) 1] menu2"
global enable_Adjacency_OSPFv3 global enable_Adjacency_OSPFv3
set enable_Adjacency_OSPFv3 0 set enable_Adjacency_OSPFv3 0
$m.adj add checkbutton -label "OSPFv3" -variable enable_Adjacency_OSPFv3 \ $m.adj add checkbutton -label "OSPFv3" -variable enable_Adjacency_OSPFv3 \
-command "[lindex $widgets(Adjacency) 1] menu3" -command "[lindex $widgets(Adjacency) 1] menu3"
global enable_Adjacency_OLSR global enable_Adjacency_OLSR
set enable_Adjacency_OLSR 0 set enable_Adjacency_OLSR 0
$m.adj add checkbutton -label "OLSR" -variable enable_Adjacency_OLSR \ $m.adj add checkbutton -label "OLSR" -variable enable_Adjacency_OLSR \
-command "[lindex $widgets(Adjacency) 1] menu4" -command "[lindex $widgets(Adjacency) 1] menu4"
global enable_Adjacency_OLSRv2 global enable_Adjacency_OLSRv2
set enable_Adjacency_OLSRv2 0 set enable_Adjacency_OLSRv2 0
$m.adj add checkbutton -label "OLSRv2" -variable enable_Adjacency_OLSRv2 \ $m.adj add checkbutton -label "OLSRv2" -variable enable_Adjacency_OLSRv2 \

File diff suppressed because it is too large Load diff

View file

@ -1,24 +0,0 @@
CORE kernel patches
For information on the kernel modules ng_pipe and ng_wlan, see the README files in their respective directories. You should run the make && make install from
the module directories for CORE to work properly.
FreeBSD 8.x requires the small patches to allow per-node directories.
The FreeBSD 7.x version of CORE does not require the patch included here.
Instead you should download the latest vimage_7 kernel from:
http://imunes.net/virtnet/
The FreeBSD 4.11 version of CORE requires the included patch to work. See the
CORE manual for patching details.
ng_pipe module you should install with FreeBSD 4.11 or 7.x
ng_wlan module you should install with FreeBSD 4.11 or 7.x
4.11-R-CORE.diff patch you should use with FreeBSD 4.11
freebsd7-config-CORE config that you may use with vimage_7 kernels
freebsd7-config-COREDEBUG debugging config for use with vimage_7 kernels
vimage_7-CORE.diff patch to add multicast routing to vimage_7_20081015
imunes-8.0-RELEASE.diff per-node directories, persistent hub/switch, and
traffic snopping for wireshark for FreeBSD 8.0
symlinks-8.1-RELEASE.diff per-node directories for FreeBSD 8.1

View file

@ -1,20 +0,0 @@
#
# VIMAGE - sample kernel configuration file with a virtualized network stack
# configure.
#
# $FreeBSD$
#
include GENERIC
ident CORE
options IPSEC
device crypto
options VIMAGE
options IPFIREWALL
options IPFIREWALL_DEFAULT_TO_ACCEPT #allow everything by default
#
# Some kernel subsystems and functions don't yet compile with VIMAGE. Remove
# from the configuration for now.
#
nooptions SCTP

View file

@ -1,22 +0,0 @@
#
# VIMAGE - sample kernel configuration file with a virtualized network stack
# configure.
#
# $FreeBSD$
#
include GENERIC
ident COREDEBUG
device crypto
options IPSEC
options VIMAGE
options DDB
options GDB
options KDB
options KDB_TRACE
#
# Some kernel subsystems and functions don't yet compile with VIMAGE. Remove
# from the configuration for now.
#
nooptions SCTP

View file

@ -1,11 +0,0 @@
# this is the FreeBSD 8.x kernel configuration file for CORE
include GENERIC
ident CORE
options VIMAGE
nooptions SCTP
options IPSEC
device crypto
options IPFIREWALL
options IPFIREWALL_DEFAULT_TO_ACCEPT

View file

@ -1,372 +0,0 @@
# This patch is from http://imunes.net/imunes-8.0-RC3.diff
#
# This patch enables per-node directories, persistent hub/switch nodes, traffic
# snooping for wireshark, and disallows vlan interfaces within a jail.
diff -drup src-org/sys/kern/vfs_lookup.c src/sys/kern/vfs_lookup.c
--- src-org/sys/kern/vfs_lookup.c 2009-10-25 01:10:29.000000000 +0000
+++ src/sys/kern/vfs_lookup.c 2009-11-11 12:46:02.000000000 +0000
@@ -59,6 +59,8 @@ __FBSDID("$FreeBSD: src/sys/kern/vfs_loo
#include <sys/ktrace.h>
#endif
+#include <net/vnet.h>
+
#include <security/audit/audit.h>
#include <security/mac/mac_framework.h>
@@ -72,6 +74,19 @@ SDT_PROBE_DEFINE3(vfs, namei, lookup, en
"unsigned long");
SDT_PROBE_DEFINE2(vfs, namei, lookup, return, "int", "struct vnode *");
+#ifdef VIMAGE
+#define IMUNES_SYMLINK_HACK
+#endif
+
+#ifdef IMUNES_SYMLINK_HACK
+static VNET_DEFINE(int, morphing_symlinks);
+#define V_morphing_symlinks VNET(morphing_symlinks)
+
+SYSCTL_VNET_INT(_vfs, OID_AUTO, morphing_symlinks, CTLFLAG_RW,
+ &VNET_NAME(morphing_symlinks), 0,
+ "Resolve @ to vimage name in symlinks");
+#endif
+
/*
* Allocation zone for namei
*/
@@ -333,6 +348,44 @@ namei(struct nameidata *ndp)
error = ENOENT;
break;
}
+#ifdef IMUNES_SYMLINK_HACK
+ /*
+ * If the symbolic link includes a special character '@',
+ * and V_morphing_symlinks is set, substitute the first
+ * occurence of '@' with full path to jail / vimage name.
+ * If the full path includes subhierarchies, s/./\// when
+ * expanding '@' to jail / vimage name.
+ *
+ * XXX revisit buffer length checking.
+ */
+ CURVNET_SET_QUIET(TD_TO_VNET(curthread));
+ if (V_morphing_symlinks) {
+ char *sp = strchr(cp, '@');
+
+ if (sp) {
+ char *vname = td->td_ucred->cr_prison->pr_name;
+ int vnamelen = strlen(vname);
+ int i;
+
+ if (vnamelen >= auio.uio_resid) {
+ if (ndp->ni_pathlen > 1)
+ uma_zfree(namei_zone, cp);
+ error = ENAMETOOLONG;
+ CURVNET_RESTORE();
+ break;
+ }
+ bcopy(sp + 1, sp + vnamelen,
+ linklen - (sp - cp));
+ bcopy(td->td_ucred->cr_prison->pr_name,
+ sp, vnamelen);
+ linklen += (vnamelen - 1);
+ for (i = 0; i < vnamelen; i++)
+ if (sp[i] == '.')
+ sp[i] = '/';
+ }
+ }
+ CURVNET_RESTORE();
+#endif
if (linklen + ndp->ni_pathlen >= MAXPATHLEN) {
if (ndp->ni_pathlen > 1)
uma_zfree(namei_zone, cp);
diff -drup src-org/sys/net/bpf.c src/sys/net/bpf.c
--- src-org/sys/net/bpf.c 2009-10-25 01:10:29.000000000 +0000
+++ src/sys/net/bpf.c 2009-11-11 12:46:02.000000000 +0000
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD: src/sys/net/bpf.c,v
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
+#include <sys/ctype.h>
#include <sys/fcntl.h>
#include <sys/jail.h>
#include <sys/malloc.h>
@@ -1435,9 +1436,34 @@ bpf_setif(struct bpf_d *d, struct ifreq
struct bpf_if *bp;
struct ifnet *theywant;
+#define XVNET_BPF_SNOOPING
+#if defined(VIMAGE) && defined(XVNET_BPF_SNOOPING)
+ struct vnet *target_vnet = curvnet;
+ char *c;
+
+ /* Attempt to attach to an ifnet in a foreign vnet, specified as @ */
+ c = rindex(ifr->ifr_name, '@');
+ if ( c != NULL ) {
+ struct prison *target_pr;
+
+ *c++ = 0;
+ if (!isascii(*c) && !isdigit(*c))
+ return ENXIO;
+ target_pr = prison_find_name(curthread->td_ucred->cr_prison, c);
+ if (target_pr == NULL)
+ return ENXIO;
+ target_vnet = target_pr->pr_vnet;
+ }
+ CURVNET_SET_QUIET(target_vnet);
+#endif
+
theywant = ifunit(ifr->ifr_name);
- if (theywant == NULL || theywant->if_bpf == NULL)
+ if (theywant == NULL || theywant->if_bpf == NULL) {
+#if defined(VIMAGE) && defined(XVNET_BPF_SNOOPING)
+ CURVNET_RESTORE();
+#endif
return (ENXIO);
+ }
bp = theywant->if_bpf;
@@ -1477,6 +1503,9 @@ bpf_setif(struct bpf_d *d, struct ifreq
BPFD_LOCK(d);
reset_d(d);
BPFD_UNLOCK(d);
+#if defined(VIMAGE) && defined(XVNET_BPF_SNOOPING)
+ CURVNET_RESTORE();
+#endif
return (0);
}
diff -drup src-org/sys/net/if.c src/sys/net/if.c
--- src-org/sys/net/if.c 2009-10-25 01:10:29.000000000 +0000
+++ src/sys/net/if.c 2009-11-11 12:46:02.000000000 +0000
@@ -813,6 +813,14 @@ if_detach_internal(struct ifnet *ifp, in
struct ifnet *iter;
int found = 0;
+ /*
+ * Detach from any vlan, bridge or lagg ifnets linked to us.
+ * A small though unlikely window for a race from here to ifp
+ * unlinking from ifnet list is possible, hence we repeat the
+ * procedure once again further bellow. XXX.
+ */
+ EVENTHANDLER_INVOKE(ifnet_departure_event, ifp);
+
IFNET_WLOCK();
TAILQ_FOREACH(iter, &V_ifnet, if_link)
if (iter == ifp) {
diff -drup src-org/sys/net/if_llatbl.c src/sys/net/if_llatbl.c
--- src-org/sys/net/if_llatbl.c 2009-10-25 01:10:29.000000000 +0000
+++ src/sys/net/if_llatbl.c 2009-11-11 12:53:49.000000000 +0000
@@ -57,11 +57,14 @@ __FBSDID("$FreeBSD: src/sys/net/if_llatb
MALLOC_DEFINE(M_LLTABLE, "lltable", "link level address tables");
-static SLIST_HEAD(, lltable) lltables = SLIST_HEAD_INITIALIZER(lltables);
+static VNET_DEFINE(SLIST_HEAD(, lltable), lltables);
+#define V_lltables VNET(lltables)
extern void arprequest(struct ifnet *, struct in_addr *, struct in_addr *,
u_char *);
+static void vnet_lltable_init(void);
+
struct rwlock lltable_rwlock;
RW_SYSINIT(lltable_rwlock, &lltable_rwlock, "lltable_rwlock");
@@ -75,7 +78,7 @@ lltable_sysctl_dumparp(int af, struct sy
int error = 0;
LLTABLE_RLOCK();
- SLIST_FOREACH(llt, &lltables, llt_link) {
+ SLIST_FOREACH(llt, &V_lltables, llt_link) {
if (llt->llt_af == af) {
error = llt->llt_dump(llt, wr);
if (error != 0)
@@ -157,7 +160,7 @@ lltable_free(struct lltable *llt)
KASSERT(llt != NULL, ("%s: llt is NULL", __func__));
LLTABLE_WLOCK();
- SLIST_REMOVE(&lltables, llt, lltable, llt_link);
+ SLIST_REMOVE(&V_lltables, llt, lltable, llt_link);
LLTABLE_WUNLOCK();
for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
@@ -180,7 +183,7 @@ lltable_drain(int af)
register int i;
LLTABLE_RLOCK();
- SLIST_FOREACH(llt, &lltables, llt_link) {
+ SLIST_FOREACH(llt, &V_lltables, llt_link) {
if (llt->llt_af != af)
continue;
@@ -202,7 +205,7 @@ lltable_prefix_free(int af, struct socka
struct lltable *llt;
LLTABLE_RLOCK();
- SLIST_FOREACH(llt, &lltables, llt_link) {
+ SLIST_FOREACH(llt, &V_lltables, llt_link) {
if (llt->llt_af != af)
continue;
@@ -232,7 +235,7 @@ lltable_init(struct ifnet *ifp, int af)
LIST_INIT(&llt->lle_head[i]);
LLTABLE_WLOCK();
- SLIST_INSERT_HEAD(&lltables, llt, llt_link);
+ SLIST_INSERT_HEAD(&V_lltables, llt, llt_link);
LLTABLE_WUNLOCK();
return (llt);
@@ -302,7 +305,7 @@ lla_rt_output(struct rt_msghdr *rtm, str
/* XXX linked list may be too expensive */
LLTABLE_RLOCK();
- SLIST_FOREACH(llt, &lltables, llt_link) {
+ SLIST_FOREACH(llt, &V_lltables, llt_link) {
if (llt->llt_af == dst->sa_family &&
llt->llt_ifp == ifp)
break;
@@ -367,3 +370,12 @@ lla_rt_output(struct rt_msghdr *rtm, str
return (error);
}
+
+static void
+vnet_lltable_init()
+{
+
+ SLIST_INIT(&V_lltables);
+}
+VNET_SYSINIT(vnet_lltable_init, SI_SUB_PSEUDO, SI_ORDER_FIRST, vnet_lltable_init, NULL);
+
diff -drup src-org/sys/net/if_vlan.c src/sys/net/if_vlan.c
--- src-org/sys/net/if_vlan.c 2009-10-25 01:10:29.000000000 +0000
+++ src/sys/net/if_vlan.c 2009-11-11 12:46:02.000000000 +0000
@@ -1359,6 +1359,12 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd
error = copyin(ifr->ifr_data, &vlr, sizeof(vlr));
if (error)
break;
+#ifdef VIMAGE
+ if (ifp->if_home_vnet != ifp->if_vnet) {
+ error = EPERM;
+ break;
+ }
+#endif
if (vlr.vlr_parent[0] == '\0') {
vlan_unconfig(ifp);
break;
@@ -1386,6 +1392,12 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd
case SIOCGETVLAN:
bzero(&vlr, sizeof(vlr));
+#ifdef VIMAGE
+ if (ifp->if_home_vnet != ifp->if_vnet) {
+ error = EPERM;
+ break;
+ }
+#endif
VLAN_LOCK();
if (TRUNK(ifv) != NULL) {
strlcpy(vlr.vlr_parent, PARENT(ifv)->if_xname,
diff -drup src-org/sys/netgraph/ng_bridge.c src/sys/netgraph/ng_bridge.c
--- src-org/sys/netgraph/ng_bridge.c 2009-10-25 01:10:29.000000000 +0000
+++ src/sys/netgraph/ng_bridge.c 2009-11-11 12:46:02.000000000 +0000
@@ -105,6 +105,7 @@ struct ng_bridge_private {
u_int numBuckets; /* num buckets in table */
u_int hashMask; /* numBuckets - 1 */
int numLinks; /* num connected links */
+ int persistent; /* can exist w/o any hooks */
struct callout timer; /* one second periodic timer */
};
typedef struct ng_bridge_private *priv_p;
@@ -345,13 +346,13 @@ static int
ng_bridge_newhook(node_p node, hook_p hook, const char *name)
{
const priv_p priv = NG_NODE_PRIVATE(node);
+ int linkNum = -1;
/* Check for a link hook */
if (strncmp(name, NG_BRIDGE_HOOK_LINK_PREFIX,
strlen(NG_BRIDGE_HOOK_LINK_PREFIX)) == 0) {
const char *cp;
char *eptr;
- u_long linkNum;
cp = name + strlen(NG_BRIDGE_HOOK_LINK_PREFIX);
if (!isdigit(*cp) || (cp[0] == '0' && cp[1] != '\0'))
@@ -359,6 +360,12 @@ ng_bridge_newhook(node_p node, hook_p ho
linkNum = strtoul(cp, &eptr, 10);
if (*eptr != '\0' || linkNum >= NG_BRIDGE_MAX_LINKS)
return (EINVAL);
+ } else if (strcmp(name, "anchor") == 0) {
+ linkNum = 0;
+ priv->persistent = 1;
+ }
+
+ if (linkNum >= 0 ) {
if (priv->links[linkNum] != NULL)
return (EISCONN);
priv->links[linkNum] = malloc(sizeof(*priv->links[linkNum]),
@@ -366,7 +373,7 @@ ng_bridge_newhook(node_p node, hook_p ho
if (priv->links[linkNum] == NULL)
return (ENOMEM);
priv->links[linkNum]->hook = hook;
- NG_HOOK_SET_PRIVATE(hook, (void *)linkNum);
+ NG_HOOK_SET_PRIVATE(hook, (void *)(intptr_t)linkNum);
priv->numLinks++;
return (0);
}
@@ -799,7 +806,8 @@ ng_bridge_disconnect(hook_p hook)
/* If no more hooks, go away */
if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)
- && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) {
+ && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))
+ && !priv->persistent) {
ng_rmnode_self(NG_HOOK_NODE(hook));
}
return (0);
diff -drup src-org/sys/netgraph/ng_hub.c src/sys/netgraph/ng_hub.c
--- src-org/sys/netgraph/ng_hub.c 2009-10-25 01:10:29.000000000 +0000
+++ src/sys/netgraph/ng_hub.c 2009-11-11 12:46:02.000000000 +0000
@@ -37,6 +37,7 @@
#include <netgraph/netgraph.h>
static ng_constructor_t ng_hub_constructor;
+static ng_newhook_t ng_hub_newhook;
static ng_rcvdata_t ng_hub_rcvdata;
static ng_disconnect_t ng_hub_disconnect;
@@ -44,6 +45,7 @@ static struct ng_type ng_hub_typestruct
.version = NG_ABI_VERSION,
.name = NG_HUB_NODE_TYPE,
.constructor = ng_hub_constructor,
+ .newhook = ng_hub_newhook,
.rcvdata = ng_hub_rcvdata,
.disconnect = ng_hub_disconnect,
};
@@ -57,6 +59,14 @@ ng_hub_constructor(node_p node)
return (0);
}
+static int
+ng_hub_newhook(node_p node, hook_p hook, const char *name)
+{
+ if (strcmp(name, "anchor") == 0)
+ node->nd_private = (void *) 1;
+ return (0);
+}
+
static int
ng_hub_rcvdata(hook_p hook, item_p item)
{
@@ -94,7 +104,7 @@ ng_hub_disconnect(hook_p hook)
{
if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0 &&
- NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))
+ NG_NODE_IS_VALID(NG_HOOK_NODE(hook)) && !hook->hk_node->nd_private)
ng_rmnode_self(NG_HOOK_NODE(hook));
return (0);
}

View file

@ -1,27 +0,0 @@
#
# (c)2008 the Boeing Company
#
# modified ng_pipe node
#
.if !defined(PLATFORM)
#PLATFORM=i386
PLATFORM=amd64
.endif
CFLAGS=-DBOEING_WLAN -I/usr/src/sys/${PLATFORM}/compile/CORE
KMOD= ng_pipe
SRCS= ng_pipe.c
#MAN= ng_pipe.4
# FreeBSD 4.11 is "FreeBSD" and 7.0 is "freebsd7.0"
#.if defined(OSTYPE)
#.if (${OSTYPE} == "FreeBSD")
#CFLAGS+=-DFREEBSD411
#SRCS= ng_pipe_freebsd4.c
#.endif
#.endif
.include <bsd.kmod.mk>

View file

@ -1,21 +0,0 @@
ng_pipe FreeBSD kernel module
See the copyright statement at the top of the source file.
Copyright (c) 2004, 2005, 2007 University of Zagreb
Copyright (c) 2007 FreeBSD Foundation
(c) 2008 the Boeing Company
modifications: Jeff Ahrenholz <jeffrey.m.ahrenholz@boeing.com>
More complete documentation is available in the ng_pipe(4) man page.
This version of ng_pipe has been modified as follows:
- added burst rate (or burstiness) which is the probability that the next packet
will be dropped given an error with the current packet, 0 to 100
- added jitter effect, which randomizes the delay an additional amount from
0 to jitter microseconds
- ng_wlan support added, to remove and read mbuf tags containing wlan link
effect information
- bugfix: random number generation improved from defective modulo algorithm
- bugfix: fixed mbuf dangling pointer reference when ng_pipe has both duplicates
and errors configured

File diff suppressed because it is too large Load diff

View file

@ -1,171 +0,0 @@
/*
* Copyright (c) 2004, 2007 University of Zagreb
* Copyright (c) 2007 FreeBSD Foundation
*
* This software was developed by the University of Zagreb and the
* FreeBSD Foundation under sponsorship by the Stichting NLnet and the
* FreeBSD Foundation.
*
* 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 THE 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 THE 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.
*/
#ifndef _NETGRAPH_PIPE_H_
#define _NETGRAPH_PIPE_H_
/* Node type name and magic cookie */
#define NG_PIPE_NODE_TYPE "pipe"
#define NGM_PIPE_COOKIE 200708191
/* Hook names */
#define NG_PIPE_HOOK_UPPER "upper"
#define NG_PIPE_HOOK_LOWER "lower"
#define MAX_FSIZE 16384 /* Largest supported frame size, in bytes, for BER */
#define MAX_OHSIZE 256 /* Largest supported dummy-framing size, in bytes */
/* Statistics structure for one hook */
struct ng_pipe_hookstat {
u_int64_t fwd_octets;
u_int64_t fwd_frames;
u_int64_t in_disc_octets;
u_int64_t in_disc_frames;
u_int64_t out_disc_octets;
u_int64_t out_disc_frames;
};
/* Keep this in sync with the above structure definition */
#define NG_PIPE_HOOKSTAT_INFO { \
{ "FwdOctets", &ng_parse_uint64_type }, \
{ "FwdFrames", &ng_parse_uint64_type }, \
{ "queueDropOctets", &ng_parse_uint64_type }, \
{ "queueDropFrames", &ng_parse_uint64_type }, \
{ "delayDropOctets", &ng_parse_uint64_type }, \
{ "delayDropFrames", &ng_parse_uint64_type }, \
{ NULL }, \
}
/* Statistics structure returned by NGM_PIPE_GET_STATS */
struct ng_pipe_stats {
struct ng_pipe_hookstat downstream;
struct ng_pipe_hookstat upstream;
};
/* Keep this in sync with the above structure definition */
#define NG_PIPE_STATS_INFO(hstype) { \
{ "downstream", (hstype) }, \
{ "upstream", (hstype) }, \
{ NULL }, \
}
/* Runtime structure for one hook */
struct ng_pipe_hookrun {
u_int32_t fifo_queues;
u_int32_t qin_octets;
u_int32_t qin_frames;
u_int32_t qout_octets;
u_int32_t qout_frames;
};
/* Keep this in sync with the above structure definition */
#define NG_PIPE_HOOKRUN_INFO { \
{ "queues", &ng_parse_uint32_type }, \
{ "queuedOctets", &ng_parse_uint32_type }, \
{ "queuedFrames", &ng_parse_uint32_type }, \
{ "delayedOctets", &ng_parse_uint32_type }, \
{ "delayedFrames", &ng_parse_uint32_type }, \
{ NULL }, \
}
/* Runtime structure returned by NGM_PIPE_GET_RUN */
struct ng_pipe_run {
struct ng_pipe_hookrun downstream;
struct ng_pipe_hookrun upstream;
};
/* Keep this in sync with the above structure definition */
#define NG_PIPE_RUN_INFO(hstype) { \
{ "downstream", (hstype) }, \
{ "upstream", (hstype) }, \
{ NULL }, \
}
/* Config structure for one hook */
struct ng_pipe_hookcfg {
u_int64_t bandwidth;
u_int64_t ber;
u_int32_t qin_size_limit;
u_int32_t qout_size_limit;
u_int32_t duplicate;
u_int32_t fifo;
u_int32_t drr;
u_int32_t wfq;
u_int32_t droptail;
u_int32_t drophead;
};
/* Keep this in sync with the above structure definition */
#define NG_PIPE_HOOKCFG_INFO { \
{ "bandwidth", &ng_parse_uint64_type }, \
{ "BER", &ng_parse_uint64_type }, \
{ "queuelen", &ng_parse_uint32_type }, \
{ "delaylen", &ng_parse_uint32_type }, \
{ "duplicate", &ng_parse_uint32_type }, \
{ "fifo", &ng_parse_uint32_type }, \
{ "drr", &ng_parse_uint32_type }, \
{ "wfq", &ng_parse_uint32_type }, \
{ "droptail", &ng_parse_uint32_type }, \
{ "drophead", &ng_parse_uint32_type }, \
{ NULL }, \
}
/* Config structure returned by NGM_PIPE_GET_CFG */
struct ng_pipe_cfg {
u_int64_t bandwidth;
u_int64_t delay;
u_int32_t header_offset;
u_int32_t overhead;
struct ng_pipe_hookcfg downstream;
struct ng_pipe_hookcfg upstream;
};
/* Keep this in sync with the above structure definition */
#define NG_PIPE_CFG_INFO(hstype) { \
{ "bandwidth", &ng_parse_uint64_type }, \
{ "delay", &ng_parse_uint64_type }, \
{ "header_offset", &ng_parse_uint32_type }, \
{ "overhead", &ng_parse_uint32_type }, \
{ "downstream", (hstype) }, \
{ "upstream", (hstype) }, \
{ NULL }, \
}
/* Netgraph commands */
enum {
NGM_PIPE_GET_STATS=1, /* get stats */
NGM_PIPE_CLR_STATS, /* clear stats */
NGM_PIPE_GETCLR_STATS, /* atomically get and clear stats */
NGM_PIPE_GET_RUN, /* get current runtime status */
NGM_PIPE_GET_CFG, /* get configurable parameters */
NGM_PIPE_SET_CFG, /* set configurable parameters */
};
#endif /* _NETGRAPH_PIPE_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,27 +0,0 @@
#
# (c)2006-2011 the Boeing Company
#
# ng_wlan
#
.if !defined(PLATFORM)
#PLATFORM=i386
PLATFORM=amd64
.endif
CFLAGS+=-I/usr/src/sys/${PLATFORM}/compile/CORE -DMULTICAST_LOOKUPS
# FreeBSD 4.11 is "FreeBSD" and 7.0 is "freebsd7.0"
#.if defined(OSTYPE)
#.if (${OSTYPE} == "FreeBSD")
#CFLAGS+=-DFREEBSD411
#.endif
#.endif
KMOD= ng_wlan
SRCS= ng_wlan.c
#MAN= ng_wlan.4
.include <bsd.kmod.mk>

View file

@ -1,50 +0,0 @@
ng_wlan FreeBSD kernel module
(c) 2006-2011 the Boeing Company
author: Jeff Ahrenholz <jeffrey.m.ahrenholz@boeing.com>
The ng_wlan modules implements a netgraph node that models wireless
LAN connectivity. ng_wlan extends the ng_hub node, only instead of sending
packets to each connected peer, maintains a hash table of node connectivity,
and sends packets between two nodes only when they are linked. By default all
nodes are unlinked. Nodes can be linked and unlinked using "link" and
"unlink" messages:
ngctl msg e0_n2: link { node1=0x23 node2=0x0c }
The node IDs of the two nodes are the parameters, as depicted above.
Link effects between can also be specified for each node pair. If two nodes
are linked and parameters are specified, an mbuf tag will be added to each data
packet mbuf that specifies the effects. For FreeBSD 4.11, the metadata parameter
is used instead of mbuf tags. Delay (microseconds), bandwidth
(bits per second), PER (% packet errors), duplicates (%), jitter
(microseconds), and burst (% burst errors) are supported. This tag is then
removed by the ng_pipe node and the appropriate effects are applied. Link
effects are specified with "set" and "unset" messages:
ngctl msg e0_n2: set { node1=0x23 node2=0x0c delay=50000 bandwidth=54000000 per=0 duplicate=0 jitter=5000 burst=30 }
ngctl msg e0_n2: unset { node1=0x23 node2=0x0c }
Note that a special ng_pipe module is needed (the default one does not support
the mbuf tags and some effects.)
A separate error rate and burst rate affecting all multicast packets may be
defined. Use the "mer" message:
ngctl msg e0_n2: mer { mer=20 mburst=35 }
The above example sets the multicast error rate to drop 20% of all multicast
packets, with 35% burst errors.
When MULTICAST_LOOKUPS is defined, a second lookup table is defined for each
WLAN where multicast group, source, and node pair tuples can be linked or
unlinked. This causes different forwarding behavior for multicast packets,
where non-local groups are only forwarded if the node pair has been linked
together for that group (and the normal node pair has been linked).
Usage:
ngctl msg e0_n2: mcastset { node1=0x23 node2=0x0c group=0xEF020364 source=0x0a000002 }
ngctl msg e0_n2: mcastset { node1=0x23 node2=0x0c group=0xEF020364 source=0}
ngctl msg e0_n2: mcastunset { node1=0x23 node2=0x0c group=0xEF020364 source=0 }
Once the first mcastset/mcastunset message is received, that ng_wlan will drop
all non-local multicast packets that do not have a matching source, group,
node pair entry. The source address of zero matches any IP source.

File diff suppressed because it is too large Load diff

View file

@ -1,109 +0,0 @@
/*
* Copyright (c) 2006-2011 the Boeing Company
* ng_wlan is based on ng_hub, which is:
* Copyright (c) 2004 Ruslan Ermilov
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE 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 THE 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.
*
*/
#ifndef _NETGRAPH_NG_WLAN_H_
#define _NETGRAPH_NG_WLAN_H_
/* Node type name and magic cookie. */
#define NG_WLAN_NODE_TYPE "wlan"
#define NGM_WLAN_COOKIE 1146673193
/* Control message parse info */
struct ng_wlan_config {
u_int32_t node1;
u_int32_t node2;
};
#define NG_WLAN_CONFIG_TYPE_INFO { \
{ "node1", &ng_parse_uint32_type }, \
{ "node2", &ng_parse_uint32_type }, \
{ NULL } \
}
struct ng_wlan_set_data {
u_int32_t node1;
u_int32_t node2;
u_int64_t delay; /* keep these aligned with struct ng_wlan_tag */
u_int64_t bandwidth;
u_int16_t per;
u_int16_t duplicate;
u_int32_t jitter;
u_int16_t burst;
};
#define NG_WLAN_SET_DATA_TYPE_INFO { \
{ "node1", &ng_parse_uint32_type }, \
{ "node2", &ng_parse_uint32_type }, \
{ "delay", &ng_parse_uint64_type }, \
{ "bandwidth", &ng_parse_uint64_type }, \
{ "per", &ng_parse_uint16_type }, \
{ "duplicate", &ng_parse_uint16_type }, \
{ "jitter", &ng_parse_uint32_type }, \
{ "burst", &ng_parse_uint16_type }, \
{ NULL } \
}
struct ng_wlan_mer {
uint16_t mer;
uint16_t mburst;
};
#define NG_WLAN_MER_TYPE_INFO { \
{ "mer", &ng_parse_uint16_type }, \
{ "mburst", &ng_parse_uint16_type }, \
{ NULL } \
}
#ifdef MULTICAST_LOOKUPS
struct ng_wlan_multicast_set_data {
u_int32_t node1;
u_int32_t node2;
u_int32_t group;
u_int32_t source;
};
#define NG_WLAN_MULTICAST_SET_DATA_TYPE_INFO { \
{ "node1", &ng_parse_uint32_type }, \
{ "node2", &ng_parse_uint32_type }, \
{ "group", &ng_parse_uint32_type }, \
{ "source", &ng_parse_uint32_type }, \
{ NULL } \
}
#endif /* MULTICAST_LOOKUPS */
/* List of supported Netgraph control messages */
enum {
NGM_WLAN_LINK_NODES = 1,
NGM_WLAN_UNLINK_NODES,
NGM_WLAN_NODES_SET,
NGM_WLAN_NODES_UNSET,
NGM_WLAN_NODES_GET,
NGM_WLAN_MER, /* MULTICAST_ERR */
NGM_WLAN_MULTICAST_SET, /* MULTICAST_LOOKUPS */
NGM_WLAN_MULTICAST_UNSET, /* MULTICAST_LOOKUPS */
NGM_WLAN_MULTICAST_GET, /* MULTICAST_LOOKUPS */
};
#endif /* _NETGRAPH_NG_WLAN_H_ */

View file

@ -1,60 +0,0 @@
/*
* Copyright (c) 2006-2011 the Boeing Company
* All rights reserved.
*
* author: Jeff Ahrenholz <jeffrey.m.ahrenholz@boeing.com>
*/
#define NG_TAG_WLAN 0x01
#ifdef FREEBSD411
#define WLAN_META_SIZE (sizeof(struct ng_meta))+(sizeof(struct ng_wlan_tag))
#define WLAN_META_PRIORITY 0x01
#define TAGSIZE (sizeof(struct ng_wlan_tag) - sizeof(struct meta_field_header))
#else
#define TAGSIZE (sizeof(struct ng_wlan_tag) - sizeof(struct m_tag))
#endif
#define NG_WLAN_MAX_DELAY 2000000 /* 2,000,000us = 2s */
#define NG_WLAN_MAX_BW 1000000000 /* 1,000,000,000bps = 1000M */
#define NG_WLAN_MAX_PER 100 /* 100% */
#define NG_WLAN_MAX_DUP 50 /* 50% */
#define NG_WLAN_MAX_JITTER NG_WLAN_MAX_DELAY
#define NG_WLAN_MAX_BURST NG_WLAN_MAX_PER
/* Tag data that is prepended to packets passing through the WLAN node.
*/
struct ng_wlan_tag {
#ifdef FREEBSD411
struct meta_field_header meta_hdr;
#else
struct m_tag tag;
#endif
u_int64_t delay;
u_int64_t bandwidth;
u_int16_t per;
u_int16_t duplicate;
u_int32_t jitter;
u_int16_t burst;
};
#define TAG_HAS_DATA(t) (t->delay || t->bandwidth || t->per || t->duplicate \
|| t->jitter || t->burst )
#define WLAN_TAG_ZERO(t) do { \
t->delay = 0; \
t->bandwidth = 0; \
t->per = 0; \
t->duplicate = 0; \
t->jitter = 0; \
t->burst = 0; \
} while(0);
#define WLAN_TAG_COPY(a, b) do { \
a->delay = ((struct ng_wlan_tag*)b)->delay; \
a->bandwidth = ((struct ng_wlan_tag*)b)->bandwidth; \
a->per = ((struct ng_wlan_tag*)b)->per; \
a->duplicate = ((struct ng_wlan_tag*)b)->duplicate; \
a->jitter = ((struct ng_wlan_tag*)b)->jitter; \
a->burst = ((struct ng_wlan_tag*)b)->burst; \
} while(0);

View file

@ -1,78 +0,0 @@
Index: sys/kern/vfs_lookup.c
===========================================================================
--- sys/kern/vfs_lookup.c 2010/06/17 19:18:00 #3
+++ sys/kern/vfs_lookup.c 2010/06/17 19:18:00
@@ -59,6 +59,8 @@
#include <sys/ktrace.h>
#endif
+#include <net/vnet.h>
+
#include <security/audit/audit.h>
#include <security/mac/mac_framework.h>
@@ -72,6 +74,19 @@
"unsigned long");
SDT_PROBE_DEFINE2(vfs, namei, lookup, return, "int", "struct vnode *");
+#ifdef VIMAGE
+#define IMUNES_SYMLINK_HACK
+#endif
+
+#ifdef IMUNES_SYMLINK_HACK
+static VNET_DEFINE(int, morphing_symlinks);
+#define V_morphing_symlinks VNET(morphing_symlinks)
+
+SYSCTL_VNET_INT(_vfs, OID_AUTO, morphing_symlinks, CTLFLAG_RW,
+ &VNET_NAME(morphing_symlinks), 0,
+ "Resolve @ to vimage name in symlinks");
+#endif
+
/*
* Allocation zone for namei
*/
@@ -333,6 +348,44 @@
error = ENOENT;
break;
}
+#ifdef IMUNES_SYMLINK_HACK
+ /*
+ * If the symbolic link includes a special character '@',
+ * and V_morphing_symlinks is set, substitute the first
+ * occurence of '@' with full path to jail / vimage name.
+ * If the full path includes subhierarchies, s/./\// when
+ * expanding '@' to jail / vimage name.
+ *
+ * XXX revisit buffer length checking.
+ */
+ CURVNET_SET_QUIET(TD_TO_VNET(curthread));
+ if (V_morphing_symlinks) {
+ char *sp = strchr(cp, '@');
+
+ if (sp) {
+ char *vname = td->td_ucred->cr_prison->pr_name;
+ int vnamelen = strlen(vname);
+ int i;
+
+ if (vnamelen >= auio.uio_resid) {
+ if (ndp->ni_pathlen > 1)
+ uma_zfree(namei_zone, cp);
+ error = ENAMETOOLONG;
+ CURVNET_RESTORE();
+ break;
+ }
+ bcopy(sp + 1, sp + vnamelen,
+ linklen - (sp - cp));
+ bcopy(td->td_ucred->cr_prison->pr_name,
+ sp, vnamelen);
+ linklen += (vnamelen - 1);
+ for (i = 0; i < vnamelen; i++)
+ if (sp[i] == '.')
+ sp[i] = '/';
+ }
+ }
+ CURVNET_RESTORE();
+#endif
if (linklen + ndp->ni_pathlen >= MAXPATHLEN) {
if (ndp->ni_pathlen > 1)
uma_zfree(namei_zone, cp);

View file

@ -1,14 +0,0 @@
# $FreeBSD$
PROG= vimage
LDADD= -ljail
DPADD= ${LIBJAIL}
WARNS?= 2
CFLAGS+= -I../../../sys
MAN= vimage.8
BINDIR?= /usr/sbin
.include <bsd.prog.mk>

View file

@ -1,195 +0,0 @@
.\" Copyright (c) 2002, 2003 Marko Zec <zec@fer.hr>
.\" Copyright (c) 2009 University of Zagreb
.\" Copyright (c) 2009 FreeBSD Foundation
.\"
.\" 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.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE 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 THE 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.
.\"
.\" $FreeBSD$
.\"
.Dd August 25, 2009
.Dt VIMAGE 8
.Os
.Sh NAME
.Nm vimage
.Nd manage virtual network stacks
.Sh SYNOPSIS
.Nm
.Op Fl c | m
.Ar vname
.Op Ar param=value ...
.Nm
.Fl d
.Ar vname
.Nm
.Fl l
.Op Fl rvj
.Op Ar vname
.Nm
.Fl i
.Ar vname ifname
.Op Ar newifname
.Nm
.Ar vi_name
.Op command ...
.Sh DESCRIPTION
The
.Nm
utility is an alternative user interface for controlling virtual network
stacks in FreeBSD, aimed primarily at supporting legacy applications
which are not yet converted to using
.Xr jail 8 ,
.Xr jexec 8 ,
and
.Xr jls 8 .
.
.Ss Overview
A virtual image or vimage is a jail with its own independent network
stack instance. Every process, socket and network interface present
in the system is always attached to one, and only one, virtual network
stack instance (vnet).
During system bootup sequence a default vnet
is created to which all the configured interfaces and user processes
are initially attached.
Assuming that enough system resources are
are available, a user with sufficient privileges can create and manage
a hierarchy of subordinated virtual images.
The
.Nm
command allows for creation, deletion and monitoring of virtual images,
as well as for execution of arbitrary processes in a targeted virtual
image.
.Ss Invocation
If invoked with no modifiers, the
.Nm
command spawns a new interactive shell in virtual image
.Ar vname .
If optional additional arguments following
.Ar vname
are provided, the first of those will be executed in place of the
interactive shell, and the rest of the arguments will be passed as
arguments to the executed command.
.Pp
The following modifiers are available:
.Bl -tag -width indent
.It Fl c
Create a new virtual image named
.Ar vname .
Additional arguments, if provided, may be used to specify operating
parameters different from defaults, in format
.Ar param=value .
See
.Xr jail 8
for an extensive list of available parameters.
.It Fl m
Modify the parameters of a virtual image named
.Ar vname ,
using the same syntax as with the -c form of the command.
.It Fl d
Delete the virtual image
.Ar vname .
No processes and/or sockets should exist in the target virtual image
in order for the delete request to succeed. Non-loopback interfaces
residing in the target virtual image will be reassigned to the virtual
image's parent.
.It Fl l
List the properties and statistics for virtual images one level
below the current one in the hierarchy. If an optional argument
.Ar vname
is provided, only the information regarding the target virtual image
.Ar vname
is displayed.
With the optional
.Op Ar -r
switch enabled the list will include all virtual images below the
current level in the vimage hierarchy.
Enabling the optional
.Op Ar -v
or
.Op Ar -j
switches results in a more detailed output.
.It Fl i
Move interface
.Ar ifname
to the target virtual image
.Ar vname .
Interfaces will be automatically renamed to
.So
ethXX
.Sc ,
unless an optional argument specifying the desired interface name
.Op Ar newifname
is provided.
.El
.Sh EXAMPLES
Create a new virtual image named
.So v1
.Sc ,
which is allowed to create and manage an own subhierarchy of vimages:
.Pp
.Dl vimage -c v1 children.max=100
.Pp
Execute the
.So ifconfig
.Sc command in the virtual image
.So v1
.Sc :
.Pp
.Dl vimage v1 ifconfig
.Pp
Move the interface
.So vlan0
.Sc to the virtual image
.So v1
.Sc while renaming the interface as
.So
ve0
.Sc :
.Pp
.Dl vimage -i v1 vlan0 ve0
.Pp
Show the status information for virtual image
.So v1
.Sc :
.Pp
.Dl vimage -lv v1
.Sh DIAGNOSTICS
The
.Nm
command exits 0 on success, and >0 if an error occurs.
.Sh SEE ALSO
.Xr jail 8
.Xr jexec 8
.Xr jls 8
.Sh HISTORY
Network stack virtualization framework first appeared as a patchset
against the FreeBSD 4.7 kernel in 2002, and was maintained outside
of the main FreeBSD tree.
As a result of a project sponsored by the FreeBSD Foundation and
Stiching NLNet, integrated virtualized network stack first appeared
in FreeBSD 8.0.
.Sh BUGS
Deletion of vimages / vnets is known to leak kernel memory and fail at
stopping various timers, hence may lead to system crashes.
.Sh AUTHOR
.An "Marko Zec" Aq zec@fer.hr

View file

@ -1,390 +0,0 @@
/*
* Copyright (c) 2002-2004 Marko Zec <zec@fer.hr>
* Copyright (c) 2009 University of Zagreb
* Copyright (c) 2009 FreeBSD Foundation
*
* 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 THE 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 THE 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.
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/jail.h>
#include <sys/socket.h>
#include <net/if.h>
#include <ctype.h>
#include <jail.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
typedef enum {
VI_SWITCHTO,
VI_CREATE,
VI_MODIFY,
VI_DESTROY,
VI_IFMOVE,
VI_GET
} vi_cmd_t;
typedef struct vimage_status {
char name[MAXPATHLEN]; /* Must be first field for strcmp(). */
char path[MAXPATHLEN];
char hostname[MAXPATHLEN];
char domainname[MAXPATHLEN];
int jid;
int parentjid;
int vnet;
int childcnt;
int childmax;
int cpuset;
int rawsock;
int socket_af;
int mount;
} vstat_t;
#define VST_SIZE_STEP 1024
#define MAXPARAMS 32
static int getjail(vstat_t *, int, int);
static char *invocname;
static void
usage(void)
{
fprintf(stderr,
"usage: %s [-c | -m] vname [param=value ...]\n"
" %s -d vname\n"
" %s -l[rvj] [vname]\n"
" %s -i vname ifname [newifname]\n"
" %s vname [command ...]\n",
invocname, invocname, invocname, invocname, invocname);
exit(1);
}
int
main(int argc, char **argv)
{
struct jailparam params[MAXPARAMS];
char ifname[IFNAMSIZ];
struct ifreq ifreq;
vi_cmd_t newcmd, cmd;
int recurse = 0;
int verbose = 0;
int jid, i, s, namelen;
int vst_size, vst_last;
vstat_t *vst;
char *str;
char ch;
invocname = argv[0];
newcmd = cmd = VI_SWITCHTO; /* Default if no modifiers specified. */
while ((ch = getopt(argc, argv, "cdijlmrv")) != -1) {
switch (ch) {
case 'c':
newcmd = VI_CREATE;
break;
case 'm':
newcmd = VI_MODIFY;
break;
case 'd':
newcmd = VI_DESTROY;
break;
case 'l':
newcmd = VI_GET;
break;
case 'i':
newcmd = VI_IFMOVE;
break;
case 'r':
recurse = 1;
break;
case 'v':
verbose++;
break;
case 'j':
verbose = 2;
break;
default:
usage();
}
if (cmd == VI_SWITCHTO || cmd == newcmd)
cmd = newcmd;
else
usage();
}
argc -= optind;
argv += optind;
if ((cmd != VI_GET && (argc == 0 || recurse != 0 || verbose != 0)) ||
(cmd == VI_IFMOVE && (argc < 2 || argc > 3)) ||
(cmd == VI_MODIFY && argc < 2) || argc >= MAXPARAMS)
usage();
switch (cmd) {
case VI_GET:
vst_last = 0;
vst_size = VST_SIZE_STEP;
if ((vst = malloc(vst_size * sizeof(*vst))) == NULL)
break;
if (argc == 1)
namelen = strlen(argv[0]);
else
namelen = 0;
jid = 0;
while ((jid = getjail(&vst[vst_last], jid, verbose)) > 0) {
/* Skip jails which do not own vnets. */
if (vst[vst_last].vnet != 1)
continue;
/* Skip non-matching vnames / hierarchies. */
if (namelen &&
((strlen(vst[vst_last].name) < namelen ||
strncmp(vst[vst_last].name, argv[0], namelen) != 0)
|| (strlen(vst[vst_last].name) > namelen &&
vst[vst_last].name[namelen] != '.')))
continue;
/* Skip any sub-trees if -r not requested. */
if (!recurse &&
(strlen(vst[vst_last].name) < namelen ||
strchr(&vst[vst_last].name[namelen], '.') != NULL))
continue;
/* Grow vst table if necessary. */
if (++vst_last == vst_size) {
vst_size += VST_SIZE_STEP;
vst = realloc(vst, vst_size * sizeof(*vst));
if (vst == NULL)
break;
}
}
if (vst == NULL)
break;
/* Sort: the key is the 1st field in *vst, i.e. vimage name. */
qsort(vst, vst_last, sizeof(*vst), (void *) strcmp);
for (i = 0; i < vst_last; i++) {
if (!verbose) {
printf("%s\n", vst[i].name);
continue;
}
printf("%s:\n", vst[i].name);
printf(" Path: %s\n", vst[i].path);
printf(" Hostname: %s\n", vst[i].hostname);
printf(" Domainname: %s\n", vst[i].domainname);
printf(" Children: %d\n", vst[i].childcnt);
if (verbose < 2)
continue;
printf(" Children limit: %d\n", vst[i].childmax);
printf(" CPUsetID: %d\n", vst[i].cpuset);
printf(" JID: %d\n", vst[i].jid);
printf(" PJID: %d\n", vst[i].parentjid);
printf(" Raw sockets allowed: %d\n", vst[i].rawsock);
printf(" All AF allowed: %d\n", vst[i].socket_af);
printf(" Mount allowed: %d\n", vst[i].mount);
}
free(vst);
exit(0);
case VI_IFMOVE:
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
break;
if ((jid = jail_getid(argv[0])) < 0)
break;
ifreq.ifr_jid = jid;
strncpy(ifreq.ifr_name, argv[1], sizeof(ifreq.ifr_name));
if (ioctl(s, SIOCSIFVNET, (caddr_t)&ifreq) < 0)
break;
close(s);
if (argc == 3)
snprintf(ifname, sizeof(ifname), "%s", argv[2]);
else
snprintf(ifname, sizeof(ifname), "eth0");
ifreq.ifr_data = ifname;
/* Do we need to rename the ifnet? */
if (strcmp(ifreq.ifr_name, ifname) != 0) {
/* Switch to the context of the target vimage. */
if (jail_attach(jid) < 0)
break;
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
break;
for (namelen = 0; isalpha(ifname[namelen]); namelen++);
i = 0;
/* Search for a free ifunit in target vnet. Unsafe. */
while (ioctl(s, SIOCSIFNAME, (caddr_t)&ifreq) < 0) {
snprintf(&ifname[namelen],
sizeof(ifname) - namelen, "%d", i);
/* Emergency brake. */
if (i++ == IF_MAXUNIT)
break;
}
}
if (i < IF_MAXUNIT)
printf("%s@%s\n", ifname, argv[0]);
else
printf("%s@%s\n", ifreq.ifr_name, argv[0]);
exit(0);
case VI_CREATE:
if (jail_setv(JAIL_CREATE,
"name", argv[0],
"vnet", NULL,
"host", NULL,
"persist", NULL,
"allow.raw_sockets", "true",
"allow.socket_af", "true",
"allow.mount", "true",
NULL) < 0)
break;
if (argc == 1)
exit(0);
/* Not done yet, proceed to apply non-default parameters. */
case VI_MODIFY:
jailparam_init(&params[0], "name");
jailparam_import(&params[0], argv[0]);
for (i = 1; i < argc; i++) {
for (str = argv[i]; *str != '=' && *str != 0; str++) {
/* Do nothing - search for '=' delimeter. */
}
if (*str == 0)
break;
*str++ = 0;
if (*str == 0)
break;
jailparam_init(&params[i], argv[i]);
jailparam_import(&params[i], str);
}
if (i != argc)
break;
if (jailparam_set(params, i, JAIL_UPDATE) < 0)
break;
exit(0);
case VI_DESTROY:
if ((jid = jail_getid(argv[0])) < 0)
break;
if (jail_remove(jid) < 0)
break;
exit(0);
case VI_SWITCHTO:
if ((jid = jail_getid(argv[0])) < 0)
break;
if (jail_attach(jid) < 0)
break;
if (argc == 1) {
printf("Switched to vimage %s\n", argv[0]);
if ((str = getenv("SHELL")) == NULL)
execlp("/bin/sh", invocname, NULL);
else
execlp(str, invocname, NULL);
} else
execvp(argv[1], &argv[1]);
break;
default:
/* Should be unreachable. */
break;
}
if (jail_errmsg[0])
fprintf(stderr, "Error: %s\n", jail_errmsg);
else
perror("Error");
exit(1);
}
static int
getjail(vstat_t *vs, int lastjid, int verbose)
{
struct jailparam params[32]; /* Must be > max(psize). */
int psize = 0;
bzero(params, sizeof(params));
bzero(vs, sizeof(*vs));
jailparam_init(&params[psize], "lastjid");
jailparam_import_raw(&params[psize++], &lastjid, sizeof lastjid);
jailparam_init(&params[psize], "vnet");
jailparam_import_raw(&params[psize++], &vs->vnet, sizeof(vs->vnet));
jailparam_init(&params[psize], "name");
jailparam_import_raw(&params[psize++], &vs->name, sizeof(vs->name));
if (verbose == 0)
goto done;
jailparam_init(&params[psize], "path");
jailparam_import_raw(&params[psize++], &vs->path, sizeof(vs->path));
jailparam_init(&params[psize], "host.hostname");
jailparam_import_raw(&params[psize++], &vs->hostname,
sizeof(vs->hostname));
jailparam_init(&params[psize], "host.domainname");
jailparam_import_raw(&params[psize++], &vs->domainname,
sizeof(vs->domainname));
jailparam_init(&params[psize], "children.cur");
jailparam_import_raw(&params[psize++], &vs->childcnt,
sizeof(vs->childcnt));
if (verbose == 1)
goto done;
jailparam_init(&params[psize], "children.max");
jailparam_import_raw(&params[psize++], &vs->childmax,
sizeof(vs->childmax));
jailparam_init(&params[psize], "cpuset.id");
jailparam_import_raw(&params[psize++], &vs->cpuset,
sizeof(vs->cpuset));
jailparam_init(&params[psize], "parent");
jailparam_import_raw(&params[psize++], &vs->parentjid,
sizeof(vs->parentjid));
jailparam_init(&params[psize], "allow.raw_sockets");
jailparam_import_raw(&params[psize++], &vs->rawsock,
sizeof(vs->rawsock));
jailparam_init(&params[psize], "allow.socket_af");
jailparam_import_raw(&params[psize++], &vs->socket_af,
sizeof(vs->socket_af));
jailparam_init(&params[psize], "allow.mount");
jailparam_import_raw(&params[psize++], &vs->mount, sizeof(vs->mount));
done:
vs->jid = jailparam_get(params, psize, 0);
jailparam_free(params, psize);
return (vs->jid);
}

File diff suppressed because it is too large Load diff

View file

@ -1,7 +0,0 @@
#!/bin/sh
echo Restoring /kernel.old ...
install -m 555 -o root -g wheel -fschg /kernel.old /kernel
rm -rf /modules
mv /modules.old /modules

View file

@ -1,21 +0,0 @@
#!/bin/sh
PREV=""
if [ ! -e "/boot/kernel.old" ] ; then
if [ ! -e "/boot/GENERIC" ] ; then
echo Previous kernel does not exist in /boot/kernel.old or /boot/GENERIC !
exit 1;
else
PREV="/boot/GENERIC"
fi;
else
PREV="/boot/kernel.old"
fi;
echo Removing current kernel...
chflags -R noschg /boot/kernel
rm -rf /boot/kernel
echo Restoring previous kernel from $PREV...
mv $PREV /boot/kernel
exit 0;

View file

@ -1,96 +0,0 @@
#!/bin/sh
VER=0.0
# determine FreeBSD 4.11 or 8.x
REL=`uname -r`
case "$REL" in
9.*)
echo "Using FreeBSD 9.x..."
KERN=9.x
SCRIPTVER=8.x
;;
8.*)
echo "Using FreeBSD 8.x..."
KERN=8.x
SCRIPTVER=8.x
;;
4.11-RELEASE)
echo "Using FreeBSD 4.11..."
KERN=4.11
SCRIPTVER=4.11
;;
*)
echo "What version of FreeBSD are you running (4.11/8.x) ?"
exit 1
esac
if [ "a$1" = "a" ]
then
echo "usage: ./core-kernel-release.sh 20080228 [clean]"
echo a version number is required
exit 1;
else
VER=$1
fi;
if [ "a$2" = "aclean" ]
then
echo Cleaning up...
rm -f core-kernel.pkglist.tmp
rm -f core-kernel.pkglist
rm -f core-kernel-${KERN}-${VER}.tbz
exit
fi;
# check for /kernel.new on 4.11
if [ ${KERN} = "4.11" ]
then
if [ -e "/kernel.new" ]
then
echo Note: proceeding using this kernel...
ls -al /kernel.new
else
echo "error: first copy the desired kernel to /kernel.new"
exit
fi;
fi;
#
# build the packing list
#
echo @comment ORIGIN:net/core-kernel > core-kernel.pkglist
if [ ${KERN} = "4.11" ]
# FreeBSD 4.11
then
echo @cwd / >> core-kernel.pkglist
echo kernel.new >> core-kernel.pkglist
find /modules \! -type d > core-kernel.pkglist.tmp
find /sbin/vimage >> core-kernel.pkglist.tmp
find /usr/share/man/man8/vimage.8.gz >> core-kernel.pkglist.tmp
find /sbin/ngctl >> core-kernel.pkglist.tmp
find /usr/share/man/man8/ngctl.8.gz >> core-kernel.pkglist.tmp
# FreeBSD 8.x
else
echo @cwd /boot >> core-kernel.pkglist
PWDOLD=${PWD}
cd /boot
find kernel \! -type d > ${PWDOLD}/core-kernel.pkglist.tmp
cd ${PWDOLD}
echo @cwd / >> core-kernel.pkglist.tmp
find /usr/sbin/vimage >> core-kernel.pkglist.tmp
find /usr/share/man/man8/vimage.8.gz >> core-kernel.pkglist.tmp
fi;
# remove leading '/' from lines
sed -e "s,^/,," core-kernel.pkglist.tmp >> core-kernel.pkglist
#
# build the package
#
pkg_create -c core-kernel.pkgdesc -d core-kernel.pkgdesclong -f core-kernel.pkglist -i core-kernel-preinstall-${SCRIPTVER}.sh -K core-kernel-deinstall-${SCRIPTVER}.sh -v core-kernel-${KERN}-${VER}.tbz

View file

@ -1,18 +0,0 @@
#!/bin/sh
if [ "x$2" = "xPOST-INSTALL" ]
then
install -m 555 -o root -g wheel -fschg /kernel.new /kernel
rm -f /kernel.new
echo Please reboot this machine to enable the new CORE kernel.
exit 0;
fi;
install -m 555 -o root -g wheel -fschg /kernel /kernel.old
if [ -e /modules.old ]
then
rm -rf /modules.old
fi;
mv /modules /modules.old
exit 0;

View file

@ -1,27 +0,0 @@
#!/bin/sh
if [ "x$2" = "xPOST-INSTALL" ]
then
echo Please reboot this machine to enable the new CORE kernel.
exit 0;
fi;
# PRE-INSTALL
# save the GENERIC kernel
OLDNAME=`strings /boot/kernel/kernel | tail -n 1`
if [ "x$OLDNAME" = "xGENERIC" ]
then
chflags -R noschg /boot/kernel
mv /boot/kernel /boot/GENERIC
exit 0;
fi;
# get rid of /boot/kernel.old if it is in the way
if [ -e "/boot/kernel.old" ] ; then
chflags -R noschg /boot/kernel.old
rm -rf /boot/kernel.old
fi;
chflags -R noschg /boot/kernel
mv /boot/kernel /boot/kernel.old
exit 0;

View file

@ -1 +0,0 @@
CORE FreeBSD kernel enables lightweight virtual machines

View file

@ -1 +0,0 @@
This package contains the CORE FreeBSD kernel with kernel modules. Custom modules include ng_pipe and ng_wlan. Also contains the userspace utility program vimage. This package can be used along with the CORE GUI to build emulated networks. This kernel is based on the GENERIC kernel with the VIMAGE option turned on (per-jail network stack virtualization), and with a small patch to allow per-node filesystem access.

View file

@ -1,68 +0,0 @@
#!/bin/sh
VER=`grep -m 1 "set CORE_VERSION" ../../gui/version.tcl | awk '{ print $3 }'`
ARCH=`uname -m`
# determine FreeBSD 4.11 or 7.x
REL=`uname -r`
case "$REL" in
9.*)
echo "Using FreeBSD 9.x..."
KERN=9.x
;;
8.*)
echo "Using FreeBSD 8.x..."
KERN=8.x
;;
4.11-RELEASE)
echo "Using FreeBSD 4.11..."
KERN=4.11
;;
*)
echo "What version of FreeBSD are you running (4.11/8.x) ?"
exit 1
esac
if [ "a$1" = "aclean" ]
then
echo Cleaning up...
rm -f core.pkglist.tmp
rm -f core.pkglist
rm -f core-${KERN}-${VER}.tbz
rm -rf /tmp/staging
exit
fi;
#
# build the packing list
#
echo @comment ORIGIN:net/core > core.pkglist
echo @cwd /usr/local >> core.pkglist
PKG_BASH=`pkg_info -E -x ^bash`
# for 4.11 change this back to 8.4
PKG_TCL=`pkg_info -E -x ^tcl-8.5`
PKG_TK=`pkg_info -E -x ^tk-8.5`
echo @pkgdep ${PKG_BASH} >> core.pkglist
echo @comment DEPORIGIN:shells/bash >> core.pkglist
echo @pkgdep ${PKG_TCL} >> core.pkglist
echo @comment DEPORIGIN:lang/tcl85 >> core.pkglist
echo @pkgdep ${PKG_TK} >> core.pkglist
echo @comment DEPORIGIN:x11-toolkits/tk85 >> core.pkglist
SAVEDIR=`pwd`
cd ../..
rm -rf /tmp/staging
gmake DESTDIR=/tmp/staging install
cd $SAVEDIR
find /tmp/staging/usr/local \! -type d >> core.pkglist
echo @cwd /etc >> core.pkglist
find /tmp/staging/etc \! -type d >> core.pkglist
sed -e "s,^/tmp/staging/usr/local/,," core.pkglist > core.pkglist.new1
sed -e "s,^/tmp/staging/etc/,," core.pkglist.new1 > core.pkglist
rm -f core.pkglist.new1
#
# build the package
#
pkg_create -c core.pkgdesc -d core.pkgdesclong -f core.pkglist -v core-${KERN}-${ARCH}-${VER}.tbz

View file

@ -1 +0,0 @@
Common Open Research Emulator userspace components

View file

@ -1,3 +0,0 @@
The Common Open Research Emulator (CORE) is a tool that allows you to emulate entire networks on a FreeBSD or Linux machine. You can connect these emulated networks to live networks (or to additional emulated networks) via the machine's physical interfaces. This package contains CORE userspace components for easily drawing topologies that drive lightweight virutalized network stacks.
WWW: http://www.nrl.navy.mil/itd/ncs/products/core

View file

@ -24,15 +24,7 @@ dist-hook:
rm -rf $(distdir)/xen/.svn rm -rf $(distdir)/xen/.svn
# install startup scripts based on --with-startup=option configure option # install startup scripts based on --with-startup=option configure option
# FreeBSD, init.d (default), systemd, SUSE # init.d (default), systemd, SUSE
if WANT_BSD
startupdir = /usr/local/etc/rc.d
startup_SCRIPTS = core-daemon
core-daemon: core-daemon-rc.d
cp $< $@
else
if WANT_INITD if WANT_INITD
startupdir = /etc/init.d startupdir = /etc/init.d
startup_SCRIPTS = core-daemon startup_SCRIPTS = core-daemon
@ -51,8 +43,6 @@ startup_SCRIPTS = core-daemon
core-daemon: core-daemon-init.d-SUSE core-daemon: core-daemon-init.d-SUSE
cp $< $@ cp $< $@
endif endif
# endif FreeBSD
endif
# remove extra scripts and their directories if they are empty # remove extra scripts and their directories if they are empty
uninstall-hook: uninstall-hook: