[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Callback function instead of trace-file?



On Wed, 06 Aug 1997 18:55:05 EDT, "Christoph Haenle" wrote: 
>I'm using ns-2b18 and need a possibility to see what happens to certain
>packets inside the network. I thus need to monitor the links. However, my
>simulation has a large number of links and my logfiles become soon very
>large (ca 10MB/min) if I log everything. In order to run simulations
>overnight, I don't want all traces to be written to disk. Rather, I'm
>looking for some possibility to register a callback-function that is called
>whenever a packet is enqueued, dequeued or lost on a link. If I remember
>right, this functionality was implemented in ns-1.4, but I can't find it in
>ns-2.

This functionality is available in ns-2.
Ahmed described the C++-level API, but it can be done from tcl as
well.

The attached script demonstrates how to do it.

Hopefully callbacks will be better documented by ns-2.0b18's release.
Specifically, the hacks in the enclosed script should go away and
there should be some documentation in the man page.

   -John Heidemann

----------------------------------------------------------------------
#
# ns_tracing.tcl
# $Id: ns_tracing.tcl,v 1.4 1997/08/09 01:49:26 johnh Exp $
#
# Copyright (c) 1997 University of Southern California.
# All rights reserved.                                            
#                                                                
# Redistribution and use in source and binary forms are permitted
# provided that the above copyright notice and this paragraph are
# duplicated in all such forms and that any documentation, advertising
# materials, and other materials related to such distribution and use
# acknowledge that the software was developed by the University of
# Southern California, Information Sciences Institute.  The name of the
# University may not be used to endorse or promote products derived from
# this software without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
# 

proc usage {} {
	puts stderr {usage: ns ns_tracing.tcl [options]

This program exists to demonstrate tracing via procs rather than files.

Compare
which creates the file ns_tracing.tr

with
	ns ns_tracing.tcl -trace-via-callback 1
which invokes a callback to print traces to stdout.

The tracing requires that you implement a procedure like
handle_trace_record and that you set it up with
trace-callback.

Note that the procs marked HACK HACK HACK are currently required
but should go away.
}
	exit 1
}

Class TestFeature

Source/FTP instproc fire {} {
	global opts
	$self instvar maxpkts_
	set maxpkts_ [expr $maxpkts_ + $opts(web-page-size)]
	$self start
# advance crashes the simulator,
# see <file:///~/NOTES/199706/970611#* VINT/ns/bugs>
#	$self advance $opts(web-page-size)
	# puts "$self fire to $maxpkts_"
}


#### HACK HACK HACK!  Fixes bug in ns-lib.tcl.
Simulator instproc create-trace { type file src dst } {
	$self instvar alltrace_
	set p [new Trace/$type]
	$p set src_ [$src id]
	$p set dst_ [$dst id]
	lappend alltrace_ $p
	if {$file != ""} {
		$p attach $file
	}
	return $p
}

#### HACK HACK HACK!  Should be in ns-link.tcl.
SimpleLink instproc trace-callback {ns cmd} {
	$self trace $ns {}
	foreach part {enqT_ deqT_ drpT_} {
		$self instvar $part
		set to [$self set $part]
		$to set callback_ 1
#		$to proc handle {args} "$cmd \$args"
		$to proc handle a "$cmd \$a"
	}
}

TestFeature instproc handle_trace_record {args} {
	# if you want args not as a list, call the parameter something else
	# see proc(n) for why.
	puts "handle_trace_record $args"
}

TestFeature instproc init {} {
	global opts

	# network
	$self instvar ns_ node1_ node2_ link12_
	set ns_ [new Simulator]
	set node1_ [$ns_ node]
	set node2_ [$ns_ node]
	$ns_ duplex-link $node1_ $node2_ 8Mb 100ms DropTail
	# this is gross!
 	set link12_ [$ns_ link $node1_ $node2_]

	# traffic
	$self instvar tcp_ ftp_
	set tcp_ [$ns_ create-connection TCP/Reno $node1_ TCPSink/DelAck $node2_ 0]
	set ftp_ [$tcp_ attach-source FTP]
	$ftp_ set maxpkts_ 0
	$ns_ at 0 "$ftp_ fire"

	# traces

	if {$opts(trace-via-callback)} {
		$link12_ trace-callback $ns_ "$self handle_trace_record"
	} else {
		$self instvar trace_file_
		set trace_file_ [open $opts(output) w]
		$link12_ trace $ns_ $trace_file_
	}

	# run things
	$ns_ at $opts(duration) "$self finish"
	$ns_ run
}


TestFeature instproc finish {} {
	$self instvar trace_file_
	if [info exists trace_file_] {
		close $trace_file_
	}

	exit 0
}


proc usage {} {
	puts stderr {usage: ns rbp_simulation.tcl [options]}
	exit 1
}

proc default_options {} {
	global opts opt_wants_arg

	set raw_opt_info {
		duration 10
		output ns_tracing.tr

		# packet size is 1000B
		# web page size in 10 pkts
		web-page-size 10

		trace-via-callback 0
	}

	while {$raw_opt_info != ""} {
		if {![regexp "^\[^\n\]*\n" $raw_opt_info line]} {
			break
		}
		regsub "^\[^\n\]*\n" $raw_opt_info {} raw_opt_info
		set line [string trim $line]
		if {[regexp "^\[ \t\]*#" $line]} {
			continue
		}
		if {$line == ""} {
			continue
		} elseif [regexp {^([^ ]+)[ ]+([^ ]+)$} $line dummy key value] {
			set opts($key) $value
			set opt_wants_arg($key) 1
		} else {
			set opt_wants_arg($key) 0
			# die "unknown stuff in raw_opt_info\n"
		}
	}
}

proc process_args {} {
	global argc argv opts opt_wants_arg

	default_options
	for {set i 0} {$i < $argc} {incr i} {
		set key [lindex $argv $i]
		if {$key == "-?" || $key == "--help" || $key == "-help" || $key == "-h"} {
			usage
		}
		regsub {^-} $key {} key
		if {![info exists opt_wants_arg($key)]} {
			puts stderr "unknown option $key";
			usage
		}
		if {$opt_wants_arg($key)} {
			incr i
			set opts($key) [lindex $argv $i]
		} else {
			set opts($key) [expr !opts($key)]
		}
	}
}

proc main {} {
	process_args
	new TestFeature
}

main