1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
|
\chapter{Emulation}
\label{sec:emulation}
This chapter describes the {\em emulation} facility
of \ns.
Emulation refers to the ability to introduce the
simulator into a live network.
Special objects within the simulator are capable
of introducing live traffic into the simulator and
injecting traffic from the simulator into the
live network.
\textbf{Emulator caveats:}
\begin{itemize}
\item While the interfaces described below
are not expected to change drastically,
this facility is still under development and
should be considered experimental and subject to change.
\item The facility described here has been
developed under FreeBSD 2.2.5, and use on other systems
has not been tested by the author.
\item Because of the currently limited portability of emulation, it
is only compiled into \emph{nse}
(build it with ``make nse''),
not standard ns.
\end{itemize}
\section{Introduction}
The emulation facility can be subdivided into
two modes:
\begin{enumerate}
\item {\sf opaque mode} -- live data treated as opaque data packets
\item {\sf protocol mode} -- live data may be interpreted/generated by simulator
\end{enumerate}
In opaque mode, the simulator
treats network data as uninterpreted packets.
In particular, real-world protocol fields
are not directly manipulated by the simulator.
In opaque mode, live data packets may be dropped, delayed, re-ordered, or
duplicated, but because no protocol processing is performed,
protocol-specific traffic manipulation scenarios (e.g. ``drop the TCP segment
containing a retransmission of sequence number 23045'') may not be performed.
In protocol mode, the simulator is able to interpret and/or generate
live network traffic containing arbitrary field assignments.
{\bf To date (Mar 1998), only Opaque Mode is currently implemented}.
The interface between the simulator and live network is provided by
a collection of objects including {\em tap agents} and {\em network objects}.
Tap agents embed live network data into simulated packets and
vice-versa.
Network objects are installed in tap agents and provide an entrypoint
for the sending and receipt of live data.
Both objects are described in the following sections.
When using the emulation mode, a special version of the system
scheduler is used: the {\tt RealTime} scheduler.
This scheduler uses the same underlying structure as the
standard calendar-queue based scheduler, but ties the execution of
events to real-time.
It is described below.
\section{Real-Time Scheduler}
The real-time scheduler implements a soft real-time scheduler
which ties event execution within the simulator to real time.
Provided sufficient CPU horsepower is available to keep up
with arriving packets, the simulator virtual time should closely
track real-time.
If the simulator becomes too slow to keep up with elapsing real
time, a warning is continually produced if the skew exceeds a
pre-specified constant ``slop factor'' (currently 10ms).
The main dispatch loop is found in the routine {\tt RealTimeScheduler::run()},
in the file {\tt scheduler.cc}.
It follows essentially the following algorithm:
\begin{itemize}
\item While simulator is not halted
\begin{itemize}
\item get current real time (``now'')
\item dispatch all pending simulator events prior to now
\item fetch next (future) event if there is one
\item delay until the next simulator event is ready or a Tcl event occurs
\item if a tcl event occured, re-insert next event in simulator event queue and continue
\item otherwise, dispatch simulator event, continue
\item if there was no future even, check for Tcl events and continue
\end{itemize}
\end{itemize}
The real-time scheduler should always be used with the emulation facility.
Failure to do so may easily result in the simulator running faster
than real-time.
In such cases, traffic passing through the simulated network will
not be delayed by the proper amount of time.
Enabling the real-time scheduler requires the
following specification at the beginning of a simulation script:
\begin{program}
set ns [new Simulator]
$ns use-scheduler RealTime
\end{program}
\section{Tap Agents}
The class {\tt TapAgent} is a simple class derived from the base
{\tt Agent} class.
As such, it is able to generate simulator packets containing
arbitrarily-assigned values within the \ns~common header.
The tap agent handles the setting of the common header packet
size field and the type field.
It uses the packet type {\tt PT\_LIVE} for packets injected
into the simulator.
Each tap agent can have at most one associated network object, although
more than one tap agent may be instantiated on a single simulator node.
\paragraph{Configuration}
Tap agents are able to send and receive packets to/from an
associated {\tt Network} object.
Assuming a network object {\tt \$netobj} refers to a network
object, a tap agent is configured using the {\tt network} method:
\begin{verbatim}
set a0 [new Agent/Tap]
$a0 network $netobj
$a0 set fid_ 26
$a0 set prio_ 2
$ns connect $a0 $a1
\end{verbatim}
Note that the configuration of the flow ID and priority are
handled through the {\tt Agent} base class.
The purpose of setting the flow id field in the common header
is to label packets belonging to particular flows of live data.
Such packets can be differentially treated with respect
to drops, reorderings, etc.
The {\tt connect} method instructs agent {\tt \$a0} to send
its live traffic to the {\tt \$a1} agent via the current
route through the simulated topology.
\section{Network Objects}
\label{sec:networkobj}
Network objects provide access to a live network.
There are several forms of network objects, depending on the
protocol layer specified for access to the underlying network,
in addition to the facilities provided by the host operating system.
Use of some network objects requires special access
privileges where noted.
Generally, network objects provide an entrypoint into the live
network at a particular protocol layer (e.g. link, raw IP, UDP, etc)
and with a particular access mode (read-only, write-only, or read-write).
Some network objects provide specialized facilities such as filtering
or promiscuous access (i.e. the pcap/bpf network object)
or group membership (i.e. UDP/IP multicast).
The C++ class {\tt Network} is provided as a base class from
which specific network objects are derived.
Three network objects are currently supported: pcap/bpf, raw IP,
and UDP/IP.
Each are described below.
\subsection{Pcap/BPF Network Objects}
These objects provide an extended interface to the LBNL packet capture
library (libpcap).
(See {\tt ftp://ftp.ee.lbl.gov/libpcap.tar.Z} for more info).
This library provides the ability to capture link-layer frames
in a promiscuous fashion from network interface drivers
(i.e. a copy is made for those programs making use of libpcap).
It also provides the ability to read and write packet trace
files in the ``tcpdump'' format.
The extended interface provided by \ns~also allows for writing
frames out to the network interface driver, provided the driver
itself allows this action.
Use of the library to capture or create live traffic may be protected;
one generally requires at least read access to the system's packet filter
facility which may need to be arranged through a system administrator.
The packet capture library works on several UNIX-based platforms.
It is optimized for use with the
Berkeley Packet Filter (BPF)~\cite{BPF93},
and provides a filter compiler for the BPF pseudomachine machine code.
On most systems supporting it,
a kernel-resident BPF implementation processes the filter code, and
applies the resulting pattern matching instructions to received frames.
Those frames matching the patterns are received through the BPF machinery;
those not matching the pattern are otherwise unaffected.
BPF also supports sending link-layer frames.
This is generally not suggested, as an entire properly-formatted frame
must be created prior to handing it off to BPF.
This may be problematic with respect to assigning proper link-layer headers
for next-hop destinations.
It is generally preferable to use the raw IP network object for sending
IP packets, as the system's routing function will be used to determine
proper link-layer encapsulating headers.
\paragraph{Configuration}
Pcap network objects may be configured as either associated with a
live network or with a trace file.
If associated with a live network, the particular network interface
to be used may be specified, as well as an optional promiscuous flag.
As with all network objects, they may be opened for reading or writing.
Here is an example:
\begin{verbatim}
set me [exec hostname]
set pf1 [new Network/Pcap/Live]
$pf1 set promisc_ true
set intf [$pf1 open readonly]
puts "pf1 configured on interface $intf"
set filt "(ip src host foobar) and (not ether broadcast)"
set nbytes [$pf1 filter $filt]
puts "filter compiled to $nbytes bytes"
puts "drops: [$pf1 pdrops], pkts: [$pf1 pkts]"
\end{verbatim}
This example first determines the name of the local system which
will be used in constructing a BPF/libpcap filter predicate.
The {\tt new Network/Pcap/Live} call creates an instance of the
pcap network object for capturing live traffic.
The {\tt promisc\_} flag tells the packet filter whether it should
configure the undelying interface in promiscuous mode (if it is supported).
The {\tt open} call activates the packet filter, and may be specified
as {\tt readonly}, {\tt writeonly}, or {\tt readwrite}.
It returns the name of the network interface the filter is associated
with.
The {\tt open} call takes an optional extra parameter (not illustrated)
indicating the name of the interface to use in cases where a particular
interface should be used on a multi-homed host.
The {\tt filter} method is used to create a BPF-compatible packet
filter program which is loaded into the underlying BPF machinery.
The {\tt filter} method returns the number of bytes used by the
filter predicate.
The {\tt pdrops} and {\tt pkts} methods are available for statistics
collection.
They report the number of packets dropped by the filter due to
buffer exhaustion and the
total number of packets that arrived at the filter, respectively
({\em not} the number of packets accepted by the filter).
\subsection{IP Network Objects}
These objects provide raw access to the IP protocol, and allow
the complete specification of IP packets (including header).
The implementation makes use of a {\em raw socket}.
In most UNIX systems, access to such sockets requires super-user privileges.
In addition, the interface to raw sockets is somewhat less standard than
other types of sockets.
The class {\tt Network/IP} provides raw IP functionality plus a
base class from
which other network objects implementing higher-layer protocols
are derived.
\paragraph{Configuration}
The configuration of a raw IP network object is comparatively
simple.
The object is not associated with any particular physical network
interface; the system's IP routing capability will be used to
emit the specified datagram out whichever interface is required
to reach the destination address contained in the header.
Here is an example of configuring an IP object:
\begin{verbatim}
set ipnet [new Network/IP]
$ipnet open writeonly
...
$ipnet close
\end{verbatim}
The IP network object supports only the {\tt open} and {\tt close}
methods.
\subsection{IP/UDP Network Objects}
These objects provide access to the system's UDP implementation
along with support for IP multicast group membership operations.
{\bf IN PROGRESS}
\section{An Example}
The following code illustrates a small but complete
simulation script for setting up an emulation test using BPF and
IP network objects.
It was run on a multi-homed machine, and the simulator essentially
provides routing capability by reading frames from one interface,
passing them through the simulated network, and writing them
out via the raw IP network object:
\begin{program}
set me "10.0.1.1"
set ns [new Simulator]
$ns use-scheduler RealTime
#
# we want the test machine to have ip forwarding disabled, so
# check this (this is how to do so under FreeBSD at least)
#
set ipforw [exec sysctl -n net.inet.ip.forwarding]
if { $ipforw } {
puts "can not run with ip forwarding enabled"
exit 1
}
#
# allocate a BPF type network object and a raw-IP object
#
set bpf0 [new Network/Pcap/Live]
set bpf1 [new Network/Pcap/Live]
$bpf0 set promisc_ true
$bpf1 set promisc_ true
set ipnet [new Network/IP]
set nd0 [$bpf0 open readonly fxp0]
set nd1 [$bpf1 open readonly fxp1]
$ipnet open writeonly
#
# try to filter out weird stuff like netbios pkts, arp requests, dns,
# also, don't catch stuff to/from myself or broadcasted
#
set notme "(not ip host $me)"
set notbcast "(not ether broadcast)"
set ftp "and port ftp-data"
set f0len [$bpf0 filter "(ip dst host bit) and $notme and $notbcast"]
set f1len [$bpf1 filter "(ip src host bit) and $notme and $notbcast"]
puts "filter lengths: $f0len (bpf0), $f1len (bpf1)"
puts "dev $nd0 has address [$bpf0 linkaddr]"
puts "dev $nd1 has address [$bpf1 linkaddr]"
set a0 [new Agent/Tap]
set a1 [new Agent/Tap]
set a2 [new Agent/Tap]
puts "install nets into taps..."
$a0 network $bpf0
$a1 network $bpf1
$a2 network $ipnet
set node0 [$ns node]
set node1 [$ns node]
set node2 [$ns node]
$ns simplex-link $node0 $node2 10Mb 10ms DropTail
$ns simplex-link $node1 $node2 10Mb 10ms DropTail
$ns attach-agent $node0 $a0
$ns attach-agent $node1 $a1
$ns attach-agent $node2 $a2
$ns connect $a0 $a2
$ns connect $a1 $a2
puts "okey"
$ns run
\end{program}
\section{Commands at a glance}
\label{sec:emulationcommand}
Following is a list of emulation related commands:
\begin{flushleft}
\code{$ns_ use-scheduler RealTime}\\
This command sets up the real-time scheduler. Note that a real-time scheduler
should be used with any emulation facility. Otherwise it may result the simulated network
running faster than real-time.
\code{set netob [new Network/<network-object-type>]}\\
This command creates an instance of a network object. Network objects are used
to access a live network. Currently the types of network objects available
are Network/Pcap/Live, Network/IP and Network/IP/UDP. See section
\ref{sec:networkobj} for details on network objects.
\end{flushleft}
\endinput
|