Internode Nodemap - Network Status Visualization


nodemap reads a configuration file which describes a set of nodes with links between them.

It then draws the nodes and links into a GIF file, using color to indicate "problems". It also presents HTML which loads that GIF file into a web browser with an imagemap to create a degree of interactivity.

The config file is used to populate a namespace of maps, nodes, links and endpoints.

This can all happen automatically at regular intervals if you follow the installation instructions.

A map is a collection of nodes and links which will be drawn and displayed on a web page. A map has a color, which is inherited from any links within the map.

A node has a name and x/y coordinates which are used to place the node on the image, and as termination points for any links. Nodes may also have maps nested within them. Nodes inherit their color from any nested maps; if the color is not green, the node is drawn larger to draw attention to the fact that there's a problem. A node without any nested maps will always be blue.

A link references at least two nodes by name, and incorporates the definition of at least one endpoint.

An endpoint is a representation of an interface on a router or switch from which statistics will be gathered. Those statistics are used to "color" the endpoint. The state (and hence the color) of a link is the union of the states of its endpoints.

Companion programs are used to gather statistics. They either read the same config file as nodemap, or config files which are automatically generated/maintained when nodemap runs. Nodemap and its companion programs will emit compile-time errors if there are syntactical or semantic problems with the config file, and runtime warnings if it appears that syntactically-valid config file entries don't make a lot of sense.

The companion programs are called:

They will be described in subsequent sections within this README file.

Configuration File

The config file is read by a recursive descent parser.

The grammar understood by the parser looks something like this:

/* here is a comment */
/* here is 
   a multiline
   comment */
map $MAPNAME {
    image $IMAGE_PATHNAME;
    node $NODENAME {

	x $X_COORD;
	y $Y_COORD;

    link $LINKNAME {
	between $NODE1 $NODE2 ... $NODEx;
	thickness $THICKNESS;
	bandwidth $BW;
	ping $IP from $EPNAME;
	url $URL;
	endpoint $EPNAME {
	    location $NODENAME;
	    host $HOSTNAME;
	    interface $INTERFACE_NAME;
	    snmp community $COMMUNITY;

Blocks have names. All the names exist in the same namespace (so you can't call a link, map or endpoint sfo_sprint if you've already created a node called sfo_sprint). Names can contain any alphanumeric character and most punctuation symbols (so bdr1.NewYork:Gig0/3 is an appropriate name for a link). Names can't contain semicolon, space or comment characters.

"map" blocks

A map encloses links and nodes. The name of the map is used on the nodemap command line to determine which map to draw, and on the update_stats command line to determine which routers/switches to interrogate for performance stats. If a map name isn't specified on the command line, map main will be used. If the requested map isn't defined, a runtime error message will be emitted.

Each map should have an image keyword (followed by the pathname to the base image which the map will be drawn on - Must be a GIF file. No quotation marks), zero or more nodes, and zero or more links.

The background image should be low-contrast so that the objects drawn by nodemap are easily recognizeable. Internode's maps start out in life as full-color scans from the street directory, then manipulated within The GIMP by overlaying them with a white layer at about 75% opacity, then selecting "merge visible layers" in the layer dialog, then converting them to an Indexed palette with 200 colors (don't use 255 colors, otherwise there won't be enough space left in the GIF's 8-bit palette for the colors which nodemap needs to allocate). The resulting image is a "washed-out" version of the street directory map.

Example of a minimal map:

     map void {
	 image images/white.gif;

There can be multiple maps defined in a file. Maps can be nested within nodes (which will cause the enclosing node to be colored according to the state of what's inside it, and HTML will be generated to produce a popup menu over the node containing the names of any enclosed maps when the mouse pointer hovers over the node).

"node" blocks

Nodes are used to specify coordinates.

If the hide attribute is applied to a node, the node won't appear on the map but can still be used as a "waypoint" for a multinode link. This can be used to cause multiple links between the same pair of nodes to follow different paths so they don't get drawn on top of each other. You can also put "hidden" nodes on street corners and road crossings on maps if you want to draw fibre paths along the line of their physical installation, rather than "as the crow flies" between their source and destination nodes.

If the terminal attribute is applied to a node, the node is drawn as a small dot. This is usually used to indicate that the presence of the node on the map isn't supposed to be indicative of its geographical location. E.g., peering links radiating out from a POP will be 25 - 50 pixels away from the POP, but that doesn't mean they're physically located on adjoining road intersections, buildings, etc. Making the dots smaller provides a visual cue to the fact that the nodes are only being drawn so that their links can be shown on the map, not to indicate their locations.

Nodes which are terminal and hidden aren't shown at all.

A node can have zero or more maps nested within.

Nodes can have nested maps. If error conditions are present in any of those maps, the node will be drawn "large" in a color which indicates the error (see Colorization below)

Each node must have an x parameter and a y parameter to specify its coordinates on the image used by its enclosing map. The coordinates define a cartesian plane with its origin at the top-left of the enclosing map's background image.


        map sydney {
	    image /usr/local/nodemap/gifs/sydney.gif;
    	    node aapt_syd {
	        x 540;
	        y 320;

A node can have a url keyword followed by a URL (which must not contain semicolons or spaces -- escape them with % notation if required). The user will be taken to that URL if they click on the node in their web browser.

"link" blocks

Links are used to specify connections between nodes.

Each link has a between keyword which describes the nodes which the link should pass through from start to finish. At least two nodes must be specified.

A link can have a thickness keyword, followed by a number or the keywords thin, medium, thick or obese. If you've provided a number then nodemap will use it to define the pixel-width of the brush used to draw the link. thin to obese mean 1 to 4 pixels respectively.

A link can also be shaded. That causes nodemap to draw it with a dashed line (perhaps to indicate a backup link? nodemap doesn't care, it's up to you). thickness and shaded can be used together.

A link can have a bandwidth keyword followed by a number. That number is the number of bits per second of the link, and is used to dimension the "fatness" of the line that is plotted on the image to represent that link (unless you've specified thickness on the link, which will override nodemap's auto-dimensioning). If pure bits per second is inconvenient, m or mbps can be suffixed to indicate megabits per second and k or kbps can be suffixed to indicate kilobits per second. These suffixes are case- insensitive. If bandwidth is not specified in the config file, nodemap will derive it automatically by utilizing the SNMP data obtained by snmp_show_int.

A link can also have a url keyword followed by a URL (which must not contain semicolons or spaces -- escape them with % notation if required). The user will be taken to that URL if they click on the representation of the link in their web browser.

A link can have a ping keyword, followed by an IP address and an endpoint name. If this keyword is present, the update_pktloss program will gather RTT and loss statistics for this link by pinging the specified IP address from the router and interface specified in the named endpoint. For example:

      link sfo_to_sprint {
	  between san_francisco sfo_sprint;
	  ping from sfo_sprint_border;
	  endpoint sfo_sprint_border {
	      location san_francisco;
	      host border-router.sfo;
	      interface GigabitEthernet1;

The ping keyword in this example will cause update_pktloss to connect to border-router.sfo and initiate a ping to with the source address set to interface GigabitEthernet1.

If the ping should be sourced from a router/interface which isn't an endpoint for the link concerned (e.g., if a link is between a pair of switchports and you wish to ping from a router), specify @hostname:interface instead of an endpoint name on the ping command. The ping command in the example above could equally be represented as ping from @border-router.sfo:GigabitEthernet1;. It's preferable to only use that syntax when it's absolutely necessary, since encapsulating all endpoint information in one place makes it less likely that you'll forget to change something subtle next time you need to relocate a link from one place on the network to another.

A link block can have either one or two endpoints. If it has two endpoints, the "load" percentage of the link will be calculated by averaging the traffic volume in each direction. This is intended to average-out the vaguaries of varying traffic flows during update_stats's runtime, where there might be several seconds delay between sampling the endpoints at each end of the link.

"endpoint" blocks

An endpoint is a description of a place which can be interrogated for statistical information. Endpoints are used by the update_stats and update_pktloss programs to communicate with routers and switches.

update_stats will run snmp_show_int against router $HOST to obtain link utilization, description, and state information. The output is similar to the IOS exec "show interface" command, with the values obtained via SNMP.

update_pktloss will run "ping" commands (via rsh or ssh) on the specified host with the source interface set to whatever is defined in the endpoint.

Each endpoint has a location. The location must be one of the nodes listed in the enclosing link's between statement.

An endpoint can optionally have an snmp_community and/or an snmp_version. If you don't specify an snmp_community nodemap will use public as its default community. If you don't specify an snmp_version nodemap will use 2c as its default SNMP version. The syntax for SNMP version numbers is any value which is acceptable to Perl's Net::SNMP module.

Example of a link through three nodes with two endpoints:

    link syd_stm1_to_adl {
	ping from sydney:POS4/0;

	between syd

	endpoint sydney:POS4/0 {
	    location syd;
	    interface POS4/0;

	endpoint adelaide:POS4/1 {
	    location adl;
	    interface POS4/1;
	    snmp_community private;
	    snmp_version 1;


Color is used to represent state.

Link states, their corresponding colors, and the conditions which cause them to occur are listed below:

ok green
loaded yellow (85% to 95% utilization)
busy red (more than 95% utilization)
down bright red (when line protocol is down)
indeterminate grey (couldn't get stats for some reason)
lossy magenta (if packet loss rate is greater than 1%)

There is a priority order associated with some of these: "indeterminate" is overridden by "lossy". "loaded", "busy" and "lossy" are overridden by "down".

Color is also used on nodes as well as links. Nodes are normally blue, but if they contain nested maps they will be colored according to the links contained within, according to the same priority order described above. So a node will be green, unless there is at least one yellow, red, bright red, magenta or grey link inside one its nested maps (or inside one of their nested maps, etc), in which case the color of the node will reflect the color of the offending link(s).

User Interface

The nodemap user interface uses DHTML via a supported DOM. Browsers which are known to work include Gecko-derived Mozilla, Firefox, etc variants, IE 6, Konquerer, Safari, and probably many others. Browsers which are known to NOT WORK and which are likely to never be supported include IE versions prior to 5.0 and Netscape releases prior to 6.0. Sorry, it's all too hard.

The user interface takes a bit of getting used to. Each HTML page generated by nodemap consists of a title, an image, an image map and a set of "DIV" blocks with their visibility attribute set to hidden. The image is generated by drawing nodes and links on top of the GIF file described in the image keyword in the map definition.

As you move the mouse over the image, pop-up boxes will appear to describe the various elements that you "hover" over.

Hovering over a link will open a popup containing the link name, its status ("ok", "loaded", "busy", "indeterminate", "down", "lossy"), its bandwidth (in Mbps), the percentage of load which was on the link when update_stats last sampled it, the RTT of packets over the link (if the link definition includes a ping keyword), the percentage of packet loss (if the link definition includes a ping keyword and the packet loss is greater than 0%), and the line protocol state of each endpoint ("up", "down" or empty for indeterminate endpoints).

Hovering over a node will open a popup containing the node name. If the node has any nested maps, there wil be hyperlinks to those maps in the popup box. To click the links, leave the mouse stationary until the outline of the popup box turns into a dotted line (to indicate that it won't disappear when you move the mouse off its node) then click the link. If you want to dismiss the popup without clicking a link, just click anywhere else in the popup.

The popups will be transparent if your browser's DOM has alpha channel support, enabling you to see items which would otherwise be obscured behind them.

Note that popups will only "pin" themselves to the map after about 0.75 seconds of hovering, so random mouse movements won't cause them to lock themselves onto the screen.

The remaining details of the user interface are concerned with color. The color of each link is determined by the state of the link. The color of each node is derived from the color of the "worst" link inside any maps nested within the node, or blue if there are no maps inside the node. This enables a "drill-down" summarization of the status of the network -- A top level view will very simply highlight problem areas, and more detail about those problem areas can be obtained by following the links which pop-up when you point to the problems.

Any nodes which aren't green or blue have extra details added to their popups which describe why. Text such as link syd4_optus is busy at 97% in map sydney informs operators about exactly where they need to go to see a problem.

The nodemap Program

The nodemap command line looks like this:

    nodemap [ -o output-directory ] [ -c mapfile ] [ map ... ]

output-directory specifies where the HTML and GIF files generated by nodemap should be placed. It'll ordinarily be in a webroot somewhere. This directory should be populated with the stylesheets and JavaScript code from the nodemap distribution, otherwise the user interface will fail to work correctly. The output-directory defaults to the current directory.

mapfile is the pathname to the configuration file. If this argument isn't provided, it'll default to etc/ relative to the current directory.

map is the name of the map within the configuration file which you want nodemap to render. If not supplied, this argument will default to main. Multiple maps can be specified, they'll be plotted in sequence.

Output from nodemap is a pair of files for each map in the output directory: mapname.html and mapname.gif. The .html file contains an image map which references the .gif file, providing the interactivity described in the User Interface section.

The scheduler Program

scheduler is responsible for queueing and executing the other nodemap companion programs.

The scheduler command line looks like this:

    scheduler [-d] [-p] [-c config-file] [-o output-directory] [mapname]

Ordinarily scheduler will disassociate itself from its controlling terminal, turn itself into a daemon, and record its PID in /var/run/ when it is invoked. The -d flag makes it run in the foreground instead with copious debugging output sent to stderr.

The -p flag can be used to turn off scheduler's efforts to contact routers to run packet loss/latency "ping" tests. Use this flag to make it ignore ping tests in etc/ if you haven't enabled rsh/ssh access to your routers.

The -c flag points scheduler at a file. The default is etc/ relative to the "current" directory.

The -o flag is passed on to nodemap subprocesses by the scheduler, providing a way to specify the location of the output directory for GIF and HTML files generated by nodemap. This directory should be somewhere in your web server's document root heirarchy.

If mapname is specified, all of scheduler's actions will be restricted to things whic affect the named map and any nested maps needed to evaluate the named map.

At runtime, scheduler reads the nodemap config file to obtain lists of links which require ping tests, lists of routers which need their interfaces interrogated for usage stats, and lists of maps which need to be redrawn. It then arranges for each item in those lists to be processed asynchronously by subprocesses randomly distributed over a 5-minute scanning interval.

As scheduler determines that each subprocess is falling due, it determines whether adequate resources are available to reasonably execute the process without bogging-down the system. scheduler currently limits itself to having ten (10) processes executing simultaneously at any given point in time. If a new process is due for execution but starting it would mean more than ten processes would be running, scheduler will delay the new process for a random number of seconds between 0 and 30 to give it another try when the system is less loaded. scheduler records its activity and current number of free process slots in its process name as reported by ps:

    bsdunix# ps ax | grep nodemap
     2651  ??  Ss     0:37.75 nodemap sleeping for 1 seconds with 4 slots (perl)
    91950  p3  S+     0:00.00 grep nodemap

Using this strategy, large networks can be polled for statistical data even if the nodemap monitoring station is very busy.

As each process completes, scheduler reschedules it so that it'll be executed up to five minutes later.

There are currently three types of events which scheduler tries to manage:

Event typeAction
update_statsEach router mentioned as an endpoint in nodemap's config file causes an update_stats event to be inserted into scheduler's event queue. As each of these events falls due, snmp_show_int is used to poll all of the interfaces on that router which nodemap cares about.
update_pktlossEach link with a ping directive in nodemap's config file causes an update_pktloss event to be inserted into scheduler's event queue. As each of these events falls due, scheduler will fork a subprocess to issue rsh/ssh commands to the "source" router to make it ping the destination.
update_nodemapEvery 120 seconds the scheduler will invoke the nodemap program to redraw your maps.

scheduler is normally started at boot-time by the supplied etc/rc.d/ script (which takes "start", "stop" and "restart" arguments like usual rc.d scripts should).

The update_stats Program


update_stats takes the same command line arguments as nodemap. Its job is to contact all the endpoints listed for all the links in the map named on the command line and run "show interface ..." commands on them.

It does that by running the snmp_show_int program. snmp_show_int will be invoked once per router, with all the interfaces on that router batched-up and queried at the same time. The resulting output is recorded by snmp_show_int in the directory stats/router:interface. These files are read by nodemap when it is producing its images. Interface names have /'s changed to ='s prior to their creation (e.g., core3.sfo2:POS5/0 will show up in file stats/core3.sfo2:POS5=0)

update_stats forks several processes to do its work -- one per router. These processes interrogate the routers in parallel to assist update_stats performance. Each process changes its process name to reflect the router and interface it's interrogating at the time.

If an interface can't be interrogated for some reason, update_stats leaves its most recent sample in-place. Samples older than ten minutes are ignored by nodemap; this means a single failed sample is unlikely to cause nodemap to fail to render a result (although two successive failed samples are likley to lead to greyed-out links)

update_stats is usually used from the command line to do a "right now" scan of all the routers in a map to update them instantaneously when you want to see the effects of a router or link configuration change without waiting for the scheduler to get around to polling your links.

The update_pktloss Program


update_pktloss gathers loss and RTT stats for links specified in the etc/pktloss.cfg file.

etc/pktloss.cfg is automatically edited by update_stats and nodemap during the normal course of their operation (i.e., it shouldn't ever need to be edited under normal circumstances). These tools only ever add entries or modify existing entries, however. If you delete a "link" block from the config file, you will probably find it advantageous to simply remove the etc/pktloss.cfg file (it'll be recreated with the most recent data next time nodemap or update_stats executes)

Each entry in etc/pktloss.cfg contains the name of a link, the name of the router which should be used to execute ping commands, the interface on that router which will be used as a source address, and the destination IP address which should be pinged. Each ping session consists of sending 100 x 2048-byte pings with a 1 second timeout.

Due to the fact that this program uses rsh/ssh, and contains built-in assumptions about the commands needed to execute a ping on an endpoint device, it'll currently only work with Cisco IOS devices. If you are using nodemap to query non-Cisco IOS devices you won't be able to use them as ping targets in link blocks.

update_pktloss is multithreaded: it'll rsh or ssh to as many routers at the same time as it can. It'll only perform one simultaneous connection to each router, however (i.e., it won't DoS our routers with connections even if it manages to DoS its host by filling up the process table :-). It'll commit suicide after ten minutes (so any hung processes or leftover zombies will disappear within a reasonable amount of time). Each process changes its name to reflect the router name, dest IP address and source interface name for the ping it's currently doing, so ps ax | grep pinger will provide fairly descriptive output.

The output from the update_pktloss program ends up in stats/$LINKNAME.loss for each link it monitors. Each of those files contains a timestamp, the number of ping packets which were returned, and the average RTT for those pings.

If a router cannot be contacted for some reason, its stats file remains in-situ (unmodified). Stats files containing timestamps older than 10 minutes are ignored (affected links behave as if they would if the "ping" tests weren't being performed: Loss is assumed to be 0% and RTT isn't reported).

The snmp_show_int Program

This program queries a router to obtain "show interface" output for a set of interfaces. It's usually executed by update_stats -- Under normal circumstances, the only time you'll run this program directly is if you want to use the -l argument to find out which interfaces are available on a newly installed router.

Command line:

    snmp_show_int -h hostname [-n] [-l] [-v snmp-version] [-c community] [interface-list]

If -l is specified, snmp_show_int will SNMP-query the ifTable on the named host to obtain a list of available interfaces, and dump them to stdout.

If -l is not specified but a list of interfaces is, then each interface is queried and simulated "show interface" output is written into the stats directory in a file called hostname:interface-name, with any "/" charaters in the interface name replaced with "=" signs. Note that the ifTable is only queried once per command-line invocation regardless of how many interfaces are queried, so for efficiency reasons it's better to query multiple interfaces on the same router by running snmp_show_int once with all the interfaces on the same command line than it is to execute snmp_show_int separately for each interface one-at-a-time.

If -n is specified, the output will be sent to stdout instead of the file in the stats/ directory.

snmp-version is the version of the SNMP protocol which should be used to make queries. Any version string supported by the perl Net::SNMP module is supported. Version 2c is the default if this option is unspecified. Note that version 1 will suffer from fairly abysmal performance when querying routers with large numbers of interfaces due to deficiencies in SNMP v1's bulk-transfer queries. Try to use version 2c if you can.

The nodemap config file doesn't provide a way to set the SNMP version used on an endpoint-by-endpoint basis, but such a feature can be trivially added if it's ever required. Cisco devices generally support version 2c anyway.

Errors cause snmp_show_int to silently skip the interface which caused the error and move on to the next interface in the list without updating the stats file. nodemap will eventually determine that the old, unupdated stats file is "stale" and stop using it.

snmp_show_int prefers to query the OLD-CISCO-INTERFACE-MIB, which contains most of the values returned in the output of the "show interface" command in the Cisco IOS EXEC. In particular, the MIB includes locIfInBitsSec and locIfOutBitsSec containing input and output bitrates.

Some interface types don't support the OLD-CISCO-INTERFACE-MIB. When snmp_show_int attempts to query those interfaces, it'll automatically fall-back to the RFC-1213 interfaces MIB. This MIB doesn't have OIDs containing bits/sec and packets/sec rates, so they must be calculated by comparing ifInOctets and ifInUcastPkts (and corresponding output OIDs) with the previous value in the stats/ directory and calculating the rate of change. To assist this calculation, simulated "show interface" output in the stats/ directory contains a "Timestamp:" value which isn't normally present in Cisco output, which snmp_show_int can use to work out the elapsed time between samples when calculating its averages.

Examples of interfaces where the OLD-CISCO-INTERFACE-MIB is not supported include ATM PVCs on Cisco 7200 Port Adaptor interfaces, and 802.1q VLAN subinterfaces on any Cisco platform.

ATM interfaces on routers cannot be queried with snmp_show_int, although their PVC subinterfaces can (i.e., you can query ATM2/0.100, but you can't query ATM2/0). In practice this is not expected to present any serious operational issues. If you really need to know the utilization on an ATM bearer circuit, probe the interface on the ATM switch instead of on the router.



Installation of nodemap requires perl 5.005_03 or later, perl's GD module gd-1.8.4_6 or later, perl's Expect module 1.15 or later and Net::SNMP 5.0.6 or later. I've installed them through FreeBSD's package system, but that's not mandatory. If you're running FreeBSD, though, the easiest way to install the prerequisites is:

freebsd# cd /usr/ports/net/p5-SNMP && make install
freebsd# cd /usr/ports/graphics/p5-GD && make install
freebsd# cd /usr/ports/graphics/p5-GD-TextUtil && make install
freebsd# cd /usr/ports/lang/p5-Expect && make install

There are some issues with GIF support in various versions of GD. If that's a problem, change the $gd->gif() calls to $gd->png() or $gd->jpg(), and the newFromGif() call to something else. I expect that this will be a lot more configurable in future, sorry if it's hacky right now (and anyone who wants to make it configurable is welcome to contribute patches :-)

Once the prerequisites are installed, nodemap can be extracted into its runtime directory. The .tar.gz distribution file contains two subdirectories: webroot and nodemap. Put the nodemap directory wherever your local policy dictates third-party software should go (e.g., /usr/local, /opt, etc -- the location isn't critical. We've assumed it'll end up in /usr/local/nodemap, but you can put it whereever you want).

The webroot directory should be located somewhere in your web server's public webroot. We don't care which web server you use, so this directory will vary from installation to installation. The webroot directory contains the documentation and the runtime CSS and JavaScript needed for the nodemap user-interface. After execution it'll also contain the .gif and .html files which nodemap generates.

Once you've chosen your directories, edit etc/rc.d/ to tell it where the bits will be going. $SOFTWARE and $OUTPUT should reference your installation directory and HTML output directory respectively. Once you've made that change, you can copy etc/rc.d/ to your system's startup directory.

Finally, if you're intending to gather packet loss and latency statistics, you'll need to work out whether you're using ssh or rsh to gather them.

As distributed, nodemap uses ssh, but rsh is probably in wider production throughout the world (most Cisco IOS revisions don't support ssh).

If you're using rsh, you'll need to make a one-line change to -- There are two lines which say:

# uncomment the one you want, comment-out the other one
my $rcmd = "/usr/bin/ssh";    # secure(ish) (default)
#my $rcmd = "/usr/bin/rsh";   # less-secure, but more likely to be enabled

Simply comment-out the first line and uncomment the second line.


There are two ways of invoking nodemap processes.

The simplest way is to start scheduler at boot time. Everything else is taken care of by nodemap itself.

If you use this method, remember to use etc/rc.d/ restart to reinitialize it whenever you edit the nodemap config file.

The other method is to invoke it out of cron. If you don't intend to do that, you can stop reading now.


5 minute intervals are recommended for nodemap and update_stats. Ten minute intervals are ok for update_pktloss. Note that more than 10 minutes between update_pktloss and update_stats invocations can lead to the recorded statistics becoming "stale", which should be avoided if possible. Less than 10 minute intervals are not recommended for update_pktloss because it runs for ten minutes before killing itself, and if you start another one before that happens you'll end up with your process table gradually filling up with update_pktloss instances.

No (permanent) problems are caused by invoking more than one instance of the tools simultaneously. You might end up with a link or two turning up in the wrong color, but it'll correct itself next time 'round (usually five minutes later).

Example crontab entries (4.4BSD cron):

2/5 * * * * (cd /usr/local/nodemap; ./update_stats >/dev/null)
3/10 * * * * (cd /usr/local/nodemap; ./update_pktloss >/dev/null)
4/5 * * * * (cd /usr/local/nodemap; ./nodemap -o /webroot/nodemap main sydney brisbane adelaide)
# periodically remove stale entries from pktloss.cfg
0 4 * * * cp /dev/null /usr/local/nodemap/etc/pktloss.cfg

This example causes interface stats and packet-loss/RTT info to be collected, and plots the "main", "sydney", "brisbane" and "adelaide" maps every five minutes.

nodemap should only be executed after update_stats and update_pktloss have had a chance to gather the most recent statistics. If you run nodemap before the update_* commands you'll find that nodemap is plotting data which was gathered five or ten minutes ago, rather than the most recent data which comes to hand.

update_pktloss is optional. If you don't run it, you won't get loss and RTT statistics, and ping commands in the config file will be silently ignored. But everything else will continue to work as expected.

nodemap doesn't need root privileges, so run it out of the crontab of a non-root user. If you're using ping commands on links, you'll need to make sure you update your router and switch configs with appropriate additions to allow the user who is executing nodemap to ssh or rsh with enough privileges to run extended "ping" commands to collect latency and packetloss information. Make sure a read-only SNMP community is defined on your routers so that snmp_show_int can obtain interface utilization statistics.

Related Projects

Inspiration for this project was drawn from:


Internode nodemap software is Copyright ©2004 Internode Pty Ltd. Redistribution permitted according to the terms of version 2 of the GPL, which has been provided with this distribution.

Permission for redistribution under different terms can be requested from Simon Hackett <>. Silence in response should be interpreted as "No."