\input texinfo    @c -*-texinfo-*-
%
% wrs-test.in - main file for the documentation
%
%%%%

%------------------------------------------------------------------------------
%
%                         NOTE FOR THE UNAWARE USER
%                         =========================
%
%    This file is a texinfo source. It isn't the binary file of some strange
%    editor of mine. If you want ASCII, you should "make cortex-m3.txt".
%
%------------------------------------------------------------------------------

%
% This is not a conventional info file...
% I use three extra features:
%   - The '%' as a comment marker, if at beginning of line ("\%" -> "%")
%   - leading blanks are allowed (this is something I can't live without)
%   - braces are automatically escaped when they appear in example blocks
%

@comment %**start of header
@documentlanguage en
@documentencoding ISO-8859-1
@setfilename cortex-m3.info
@settitle wrs-test
@iftex
@afourpaper
@end iftex
@paragraphindent none
@comment %**end of header

@setchapternewpage off

@set update-month May 2011

@finalout

@titlepage
@title White Rabbit Switch: test procedures
@subtitle @value{update-month}
@subtitle Testing tools for Ethernet switches

@author Alessandro Rubini (@code{rubini@@gnudd.com})
@end titlepage
@headings single

@c ##########################################################################
@iftex
@contents
@end iftex


@c ##########################################################################
@node Top
@top Introduction

The @code{test/} subdirectory of @code{wr-switch-sw}
is part of the efforts related to the
@i{White Rabbit} project, a multi-company multi-lab collaboration
hosted at @code{ohwr.org}.  The testing sub-package introduces
some special-purpose tools and examples, in addition to
defining and implementing
testing procedures according to RFC-1242 and RFC-2544, as well as
RFC-2285 and RFC-2889.

As I write this page (May 2011), the RFC-related tests are not yet
available, but I suspect this introduction to remain in place for a
while after being out of date -- so please check later pages to
verify the status of testing code.

In this document, when I say @i{this package} I refer to the @i{White
Rabbit Switch Software} (a.k.a. @code{wr-switch-sw}) --
the tar file you downloaded (or the @i{git} tree you
fetched), including both the code and the documentation.

Material (code and documentation) specifically written for this
package is released according to the GNU GPL, version 2 or (at your
option) any later version.  This excludes the RFC documents that are
distributed in this package and any other works that may be added here
in later versions. Any external contribution is clearly marked as
such, unless the committer forgot to update the documentation.


@menu
* How is Testing Implemented::  
* Network Timestamping Overview::  
* The Octopus::                 
* Server and Client::           
* Description of the Tests::    
* How to Run the Test Suite::   
* Results Collected on Various Switches::  
@end menu

@c ##########################################################################
@node How is Testing Implemented
@chapter How is Testing Implemented

Testing the performances of an Ethernet switch is a generic task,
somehow detached from the underlying switch implementation.  However,
existing test tools, as far as I know, are either non-free or in some
way too simplified for the WR needs. Moreover, in WR we want to rely
on hardware timestamping whenever possible.

@menu
* RFC Compliance::              
@end menu

@c ==========================================================================
@node RFC Compliance
@section RFC Compliance

The relevant RFC Documents are included in the @code{test/rfc} subdirectory
of this package. They have been downloaded from the following locations:

@smallexample
   http://www.ietf.org/rfc/rfc1242.txt
   http://www.ietf.org/rfc/rfc2285.txt
   http://www.ietf.org/rfc/rfc2544.txt
   http://www.ietf.org/rfc/rfc2889.txt
@end smallexample

I am not aware of other specifications about testing, so I just refer
to these four files.  All documents have @i{informational}
status. This is the role of each of them and how it is being used in
developing the test programs:

@itemize @bullet
@item RFC-1242

    This document is only concerned with definitions used on other
    documents.  What is most interesting for us is the definition of
    @i{throughput} and @i{latency}. Throughput is the maximum data rate at
    which no frame is lost, not as the amount of data transmitted per
    second, as one may expect; latency is defined in two different ways
    according to whether the device is a store-and-forward or a bit
    forwarding one; we'll use the definition for bit forwarding devices.

@item RFC-2544 (which obsoletes RFC-1944)

    The document is the main definition of tests for one-to-one or
    many-to-many performance evaluation. It defines which tests vendors
    are expected to make and how to make them, relying on the definitions
    set forth by RFC-1242.  It defines the concepts of ``conditionally
    compliant'' and ``unconditionally compliant'' test suites.  The aim of
    this package is being @i{conditionally} compliant, since the number of
    recommended (but not required) tests is huge and probably not
    meaningful for our aims.  Both in the source code and in this
    description of the tests, I name the relevant sections of RFC-2544

@item RFC-2285

    Like the first document, this RFC defines the terminology for
    benchmarking tests in LAN contexts.  It extends what is defined by
    RFC-1242 with definition for a meshed networking context.

@item RFC-2889

    This is the equivalent of RFC-2544 for network topologies more complex
    than one-to-one environments.  At this point in time, I am not able to
    run any such tests, on the White Rabbit Switch,
    but they will be added in later versions of this
    package.  Meanwhile, the ``octopus'' (see @ref{The Octopus}) is
    something that somehow approaches what the RFC suggests.
    Unlike RFC-2544, this document doesn't define a
    @i{compliant} test environment.

@end itemize

The specifications for the testing are quite demanding.  Work described
here tried to reach compliance, but we are not there as this document
is being drafted.

@c ##########################################################################
@node Network Timestamping Overview
@chapter Network Timestamping Overview

This section describes the hardware timestamp mechanism of the Linux
kernel.  It is meant to be a reference for people who deal with
hardware timestamping in general or in particular within White
Rabbit.

The hardware timestamping mechanism has been pushed to the upstream
kernel by Patrick Ohly and Richard Cochran; the first official kernel
released with some related code was 2.6.30.
The description in this section refers to Linux-2.6.39, with references
to the slightly-different implementation of 2.6.35.
@c v2.6.35-rc1-1246-gc1f19b5

The official documentation can be found in
@code{Documentation/networking/timestamping.txt} and an example
program is found in the directory
@code{Documentation/networking/timestamping/}.  What is not explained
there, however, is the internal mechanism and what are the relevant
source files or data structures.

@menu
* Timestamping Implementation::  
* Timestamping Use::            
* Using HW Stamps on RTL8169::  
* Using HW Stamps on the 82575 device::  
* White Rabbit Extensions::     
@end menu

@c ==========================================================================
@node Timestamping Implementation
@section Timestamping Implementation

This is a description of stamping seen from the point of view of
the kernel; it describes what the driver is expected to do and the
flow of associated information until it reaches user space.

First, hardware timestamping must be enabled in the specific hardware
interface. This is accomplished by the interface-specific @i{ioctl}
function: the device driver must identify the @code{SIOCSHWTSTAMP}
command and use it to set or unset flags in the private data structure
of the device. Information is passed using an @code{hwstamp_config}
structure, as described in the @code{timestamping.txt} file.

Then, the socket itself must have timestamping enabled. The
socket options (set by @i{setsockopt}) are the following.

@table @code
@item SO_TIMESTAMPING
	This socket option receives a bitmask argument, specifying the
        various timestamp options that are activated. See below.
@item SO_TIMESTAMPNS
	This option has argument 0 or 1. If enabled it requests
        software stamps to be returned as nanoseconds (@code{struct timespec})
        instead of microseconds (@code{struct timeval}).
@end table

The bits in the argument of @code{SO_TIMESTAMPING} are listed below. The
numeric value is shown as well, because the @i{onestamp} tool
(introduced later) received a numeric argument.

@table @code
@item 1 = SOF_TIMESTAMPING_TX_HARDWARE
@itemx 2 = SOF_TIMESTAMPING_TX_SOFTWARE
@itemx 4 = SOF_TIMESTAMPING_RX_HARDWARE
@itemx 8 = SOF_TIMESTAMPING_RX_SOFTWARE
       The 4 bits request one or more of the four possible timestamping
       options. However I couldn't really make sense of them (in particular,
       the two @code{SOFTWARE} bits have no effect on my systems). Without
       bit 0 (@code{SOF_TIMESTAMPING_TX_HARDWARE}) no tx stamp is collected
       at all.
@item 16 = SOF_TIMESTAMPING_SOFTWARE
@itemx 32 = SOF_TIMESTAMPING_SYS_HARDWARE
@itemx 64 = SOF_TIMESTAMPING_RAW_HARDWARE
      These three bits select which @i{timespec} structures in the
      array of three (see later about the internals) are returned. Please
      note that the @code{SYS_HARDWARE} and @code{RAW_HARDWARE} bits depend
      on the device driver to be able to return such information: @code{SYS}
      is a timestamp comparable with other GMT times while @code{RAW} is
      an unrelated nanosecond counter.
@end table

@c 1 = SOF_TIMESTAMPING_TX_HARDWARE       (enables base tx stamp)
@c 2 = SOF_TIMESTAMPING_TX_SOFTWARE       (no effect)
@c 4 = SOF_TIMESTAMPING_RX_HARDWARE       (no effect)
@c 8 = SOF_TIMESTAMPING_RX_SOFTWARE       (no effect)
@c 16 = SOF_TIMESTAMPING_SOFTWARE
@c 32 = SOF_TIMESTAMPING_SYS_HARDWARE
@c 64 = SOF_TIMESTAMPING_RAW_HARDWARE

Data collection is then slightly different for transmitted and
received packets, although in both cases data reaches user space using
a ``control message'' interface. Such control messages are assembled
by the function @i{put_cmsg} (@code{net/core/scm.c}).

@c --------------------------------------------------------------------------
@subheading Receive Timestamps

For receive timestamps, the device driver should fill one or two
@i{ktime} structures in a shared space within the socket buffer.  The
@i{ktime} is basically a 64-bits nanosecond count, which may or may
not come from a @code{struct timespec} object. The @i{ktime} is opaque
and the implementation is architecture-specific (see
@code{<linux/ktime.h>}).

The following excerpt shows the typical code to be executed in the
RX interrupt handler; such code should only execute if stamping
has been enabled for this interface using @i{ioctl}:

@smallexample
    struct skb_shared_hwtstamps *tstamps = skb_hwtstamps(skb);
    struct timespec ts;
    unsigned long nano;
    ktime_t kt;

    memset(tstamps, 0, sizeof(*tstamps));

    /* fill "ts" as GMT time or a "nano" counter, in hw-specific ways */
    kt = timespec_to_ktime(ts);
    tstamps->syststamp = kt;   /* Use syststamp if your time is GMT */
    tstamps->hwtstamp = nano;  /* Or use hwtstamp for hw nanoseconds */
@end smallexample

The difference between the two values is that the @i{sys} stamp is
expected to be compared with the normal Unix time values (even if
they are not kept in sharp sync), while the @i{hw} value can only
be compared with other such values collected by the same interface.

After filling the structure within the @i{skb}, the driver
is done.  It's the network stack that will call @i{sock_recv_timestamp}
at the proper time.

@c --------------------------------------------------------------------------
@subheading sock_recv_timestamp

This function is called from one of @code{net/ipv4/ip_sockglue.c},
@code{net/ipv6/datagram.c} and @code{net/packet/af_packet.c} .

It is defined as an @i{inline} function in @code{include/net/sock.h};
it checks socket flags to know whether stamping information must be
returned or not.

The function calls @i{__sock_recv_timestamp()} if one of
these situations apply:

@itemize @bullet
@item The socket has @code{SOCK_RCVTSTAMP} set;
@item The socket has @code{SOCK_TIMESTAMPING_RX_SOFTWARE} set;
@item @code{skb->tstamp} is non-zero and the socket has
       @code{SOCK_TIMESTAMPING_SOFTWARE} set;
@item The @i{skb}'s @code{shhwtstamps->hwtstamp} is non-zero and
      the socket has @code{SOCK_TIMESTAMPING_RAW_HARDWARE} set;
@item The @i{skb}'s @code{shhwtstamps->syststamp} is non-zero and
      the socket has @code{SOCK_TIMESTAMPING_SYS_HARDWARE} set;
@end itemize

If no such condition applies, the function sets @code{sk->sk_stamp} to
the value of @code{skb->tstamp}, for the old interface by which user-space
can ask the timestamp of the last packet received using @i{ioctl} on the
socket.

@c --------------------------------------------------------------------------
@subheading __sock_recv_timestamp

The function, in @code{net/socket.c}, is in charge of actually building
the @i{cmsg}. It receives the @i{cmsg} header, the socket and the socket
buffer. It fills the @i{cmsg} with:

@itemize
@item @code{SCM_TIMESTAMPNS} information (@code{timespec}) if the socket
      has both @code{SOCK_RCVTSTAMP} and @code{SOCK_RCVTSTAMPNS}.
@item @code{SCM_TIMESTAMP} information (@code{timeval}) if the socket
      has @code{SOCK_RCVTSTAMP} alone.
@item @code{SCM_TIMESTAMPING} information (an array of three @code{timespec})
      if either of @code{SOCK_TIMESTAMPING_SOFTWARE},
      @code{SOCK_TIMESTAMPING_SYS_HARDWARE} and
      @code{SOCK_TIMESTAMPING_RAW_HARDWARE} is set. At least one and
      at most three of the structures are filled, according to the active
      flags.
@end itemize

@c --------------------------------------------------------------------------
@subheading Transmit Timestamps

Timestamps for transmitted packets cannot be retrieved during
transmission, but only at a later time. The stamp is known only when
the start-of-frame impulse passes the @i{phy} device, so you can only
retrieve it during the @i{tx-done} interrupt, not earlier.

The flow of actions that are involved in stamping is as follows:

@itemize @bullet

@item In the @i{start_xmit} device function, the driver marks timestamping
as @i{in_progress} in the socket buffer -- only if this packet is going
to be stamped. This is accomplished by setting the @code{SKBTX_IN_PROGRESS}
bit in @code{skb_shinfo(skb)->tx_flags}.

@item For those packets where @i{in_progress} is set, the @i{tx-done} interrupt function retrieves the timestamp and
calls @i{skb_tstamp_tx} (@code{net/core/skbuff.c}). Note that the
@code{SKBTX_IN_PROGRESS} flag is only used by the driver itself.

@item This @i{skb_tstamp_tx} copies over the data to a clone of the
original socket buffer, which is then enqueued to the error queue
for the socket. The @i{tx-done} code can thus release this @i{skb}
without any further special case.

@item The protocol-specific @i{receive_error} function, will then
call the same @i{sock_recv_timestamp} used for received packets.
@end itemize

This is the typical code that will run in the @i{tx-done} handler,
for those packets where @i{in_progress} was set:

@smallexample
    struct skb_shared_hwtstamps tstamps; /* local in this function */
    union skb_shared_tx *shtx;
    struct timespec ts;
    ktime_t kt;

    memset(tstamps, 0, sizeof(*tstamps));

    /* fill "ts" as GMT time or a "nano" counter, in hw-specific ways */
    kt = timespec_to_ktime(ts);
    tstamps.syststamp = kt;   /* Use syststamp if your time is GMT */
    tstamps.hwtstamp = nano;  /* Or use hwtstamp for hw nanoseconds */

    skb_tstamp_tx(skb, &shhwtstamps);
@end smallexample

Actually, the only difference in the transmit code path from the
receive code path we have seen earlier is that the structure
with the two @i{ktime} stamps is local and not in the @i{skb} itself.

Before version @code{v2.6.36-rc1-71-g2244d07} (thus, in 2.6.35 and earlier)
the @i{in_progress} marker was a field in a union hosted in the
socket buffer, but this extra level of indirection was confusing and has
been removed.

@c ==========================================================================
@node Timestamping Use
@section Timestamping Use

When you receive a packet you can get the timing data together with
the packet, while when you transmit you must receive back a copy of
your own data with the timing information added (this is the @i{clone}
of the transmitted packet, as described earlier).

In the directory @i{test/misc} of this package, you can find two simple
programs that use the timestamping features. As opposed to what is
found in the kernel sources
(@code{Documentation/networking/timestamping/timestamping.c}), these
don't do the PTP related operations but try to remain simpler.

@itemize @bullet
@item ttstamp
The ``test time stamp'' program is the smallest testing tool I came up
with, it may be used to get acquainted with the basic ideas of timestamping
while taking some measures.

@item onestamp
This is a still smaller program: it takes timestamps on just one
transmitted packet and one received packet. You can change the
@i{ioctl} arguments on the command line to get acquainted to the
meaning of the various bits.
@end itemize

The programs are based on common code, that I factorized in
the source @code{stamp-funcs.c}.  The functions in there make
the following tasks:

@table @code
@item make_stamping_socket()
	The function opens a socket issuing the stamp-related ioctl commands
	to both the socket and the network interface.

@item send_and_stamp()
@itemx recv_and_stamp()
	The functions take the same arguments as @i{send} and @i{recv},
	but collect timestamps in a static structures (that is overwritten
	at every invocation).

@item get_stamp()
	Returns the timestamps collected by either of the previous
	functions.

@item print_stamp()
	The function prints the static structures filled by either
	@i{send_and_stamp} or @i{recv_and_stamp}.
@end table

@c ==========================================================================
@node Using HW Stamps on RTL8169
@section Using HW Stamps on RTL8169

The directory @i{test/patches} in this package includes a few patches to
fake hardware timestamping with the RTL8169 Gigabit device. You can
apply them with @i{git-am} or @i{patch}.

The patches allow to test timestamping features while using a cheap
Gigabit Ethernet card.  The faked hardware timestamps are both
the @i{sys_hardware} and @i{raw_hardware} ones. The former is
faked as a timespec with only 4 digits in the @i{tv_sec} field,
while the latter has only 2 digits in the field. Both come
from @i{getnstimeofday} since we have no other timestamp source.

For example, this is what I get with my @i{onestamp} tool:

@smallexample
   tornado.root# ./onestamp eth1 0x7f
   ./onestamp: Using interface eth1, with 127 as SO_TIMESTAMPING
   tx  ns: 1299671882.829046976
   tx ns0: 1299671882.829046976
   tx ns1:       1882.829061507
   tx ns2:         82.829061507

   rx  ns: 1299671883.199960762
   rx ns0: 1299671883.199960762
   rx ns1:       1883.199960611
   rx ns2:         83.199960611
@end smallexample

As shown above, by setting all the timestamp-related bits (see
@ref{Timestamping Implementation}), we get back both software
and hardware timestamps. The former has nanosecond resolution
because we set the @code{SO_TIMESTAMPNS}, and the latter has
all three @i{timespec} structures: the software one (index 0,
which carries the same value as in plain software stamping),
the @i{sys_hardware} one (index 1) and the @i{raw_hardware} one
(index 2).

In the example you can see that the transmit faked hardware stamp is
taken after the software one, because the patch collect the time in
the tx-done interrupt. The receive faked stamp is taken slightly
before the software stamp because it is collected at interrupt time,
before passing the packet to the kernel proper.

When running @i{ttstamp}, you'll get back the 4 timestamp differences
from TX to RX, expressed in nanoseconds, for the 4 stamps. The
argument used for @code{SO_TIMESTAMPING} is 1 by default, or inherited
from the environment variable @code{STAMP_HOWTO}.  The program must
be run on a system with a loopback Ethernet cable, among the two
self-connected interfaces.

@c ==========================================================================
@node Using HW Stamps on the 82575 device
@section Using HW Stamps on the 82575 device

@b{NOTE: This is currently bugged, the numbers are repeated, I leave
it here for reference}.

@c FIXME

If you have an Intel 82575 or 82576, supported by
@code{drivers/net/igb/}, you have real hardware timestamping.  For
some reasons, you should not activate bit 4 (0x10 =
@code{SOF_TIMESTAMPING_SOFTWARE}) in @code{SO_TIMESTAMPING}, or you will
get only the software stamp. This is a sample run with the simple
@i{onestamp}:

@smallexample
   tornado.root# ./onestamp eth4 0x61
   ./onestamp: Using interface eth4, with 97 as SO_TIMESTAMPING
   tx  ns: 1299678952.801922373
   tx ns0:          0.000000000
   tx ns1: 1299673561.657943573
   tx ns2: 1299668554.247323098

   rx  ns: 1299678952.907927486
   rx ns0:          0.000000000
   rx ns1: 1299673561.657943573
   rx ns2: 1299668554.247323098
@end smallexample

@c ==========================================================================
@node White Rabbit Extensions
@section White Rabbit Extensions

@c FIXME:
Still to be written.

@c ##########################################################################
@node The Octopus
@chapter The Octopus

The octopus is a simple tool I wrote almost for fun.  It was born as a
separate package called @i{swflood} (``switch flood'') and is now
hosted in the @code{test/swflood} directory of this package.

The program is accompanied by a @code{multidump} sniffer tool, that
sniffs on several network interfaces at the same time.

@menu
* swflood::                     
* multidump::                   
@end menu

@c ==========================================================================
@node swflood
@section swflood

This program is meant to flood a switch with packets, to test how such
packets are routed to the various ports.

The host system is expected to be connected to a single switch through
several point-to-point cables.  Ideally you should run at least 3
dedicated ethernets, in order to tell packets that are broadcasted to
all the ports from ones routed to a single port.

The host ports are configured to send packets from MAC addresses of
the form @code{22:00:1x:00:yy:yy}, where "1x" represents the port
number (starting from 0x10) and yy represents a sequential number
starting from 0.  Some tests transmit from the same mac address, while
other tests change the mac address to fake a network of different
machines connected to the same cable. The program is expected to use
at most 64k MAC addresses per interface, according to the pattern
shown.

The operation of @i{swflood} is driven by a configuration file.  Each
line in the config file defines a directive.  The directive is either
a declaration, a request to send packets or a request to report
results. Each directive is parsed as a command line, so the command
procedure receives @code{argc} and @code{argv}.  Lines starting with
'#' and empty lines are discarded.

The configuration file is passed on the command line of @i{swflood}.

The following directives are supported:

@table @code
@item verbose <n> [<logfile>]

	Activate verbosity level <n>; optionally redirect verbose
	output to file <logfile>, while normal output goes to @i{stdout}.
	The log file is opened in append mode.
@c FIXME: check logging and error reports

@item iface <name> <name> ...

	Open one socket for each of these interfaces. For example:
	"@code{inface eth1 eth4 eth3 eth2}". If some interfaces cannot be
	opened only a warning is reported, but later directives may
	fail (for example if you transmit from that interface). The
	interfaces are assigned numbers starting from 0, used later
        in the program.

@item send <if> <nr> <yy:yy> [+<incr>] <aa:bb:cc:dd:ee:ff> [+<incr>]

	Send <nr> packets from interface <if>, starting from mac
	address yy:yy within the port's range, incrementing the mac
	address by <incr> each time.  Before sending each packet the
	program receives any pending frame and accounts it.

	Example: "@code{send 0  100 00:01    22:00:11:00:00:10 +1}"

	Example: "@code{send 1 1000 10:00 +1 22:00:10:00:00:01}"

	The first example above sends 100 packets from 22:00:10:00:00:01
	to 100 different target addresses (in the range of interface 2)
	The second example send 1000 packets from different addresses
	of interface 1 to address 00:01 in the range of interface 0.

@item sendas <as> <if> <nr> <yy:yy> [+<incr>] <aa:bb:cc:dd:ee:ff> [+<incr>]

	Like above, but the program sends from interface <if> using
	a sender addresss belonging to interace <as>.

@item expect <n> <n> ....

	The commands waits for 10ms to get all packets still pending
	on all the interfaces and then verifies if the number of
	packets received on all interfaces is the specified number.
	If it differs, an error is reported.

@item flush
	Resets the statistics for all interfaces.

@item repeat <letter> <number>
@itemx endr <letter>

	Trivial looping tool. Repeats all the directives from the
	"@code{repeat}" to the corresponding "@code{endr}" for <number> times.
	The identifier <letter> allows nested loops.

	Example:
@example
		send  0 100 00:00 +1 ff:ff:ff:ff:ff:ff
		flush
		repeat A 10
		 	send 1 100 00:00 22:00:10:00:00:00 +1
			expect 100 0 0 0
		endr A
@end example

	The example fakes 100 senders at interface 0, and then
	tries to transmit 10 times to all of them, each time
	expecting to get all the packets on port 0,

@item sleep <sec> [<msec>]

	Insert a delay in the data flow.

@item echo <arg> ...

	Echo constant string to stdout. The string is also
	saved to the log file, with a prefix of "# ", for ease "grep -v".
@end table

The @code{test/swflood/cfg-test} directory includes some example
configuration files. In particular @code{tablesize-test} can be used
to estimate the size of the routing table in the switch.

@code{test/swflood/results} includes tree result logs for a run of
@code{tablesize-test}. From the output, it's clear how both
@code{switch5} and @code{piccolo} have a routing table of 1k
addresses, while @code{switch6} has a table ot 8k addresses.

@c ==========================================================================
@node multidump
@section multidump

The @i{multidump} program is a simple sniffer that listens to several
network interfaces at the same time. I used it as a diagnostic tool while
writing the @i{swflood} program.

The program receives a list of interface names on the command line,
like this:

@example
    ./multidump eth1 eth2 eth3 eth4
@end example

The output is wide lines (119 characters), showing for each
packet the interface name, a timestamp and the beginning of payload:

@smallexample
eth1     1305150196.250015   00:10:a7:13:b1:1e 94:0c:6d:80:ab:d9 08.00 45.08....
@end smallexample


@c ##########################################################################
@node Server and Client
@chapter Server and Client

The test system has been designed as a client-server system, even
though the client and server are expected to run on the same computer
most of the time.

Unless you are running client and server on different computers (which
is not supported in the initial versions of the testing tools), you'll just
need to fire the client applications (see @ref{How to Run the Test
Suite}).  The client program will automatically fork a server process,
and exchange information through a @i{Unix Domain} socket.

Running the sending and receiving sides of the testing machinery on
different processes allows to exploit SMP, if the testing host is an
SMP one.  When the host system is not SMP (for example, when
a @i{White Rabbit} switch is used to test other switches) this choice
may be sub-optimal; I may consider running multi-thread instead of
multi-process in later revisions.

@c FIXME: complete server and client

@c ##########################################################################
@node Description of the Tests
@chapter Description of the Tests

@c FIXME: 
Still to be written.

@c ##########################################################################
@node How to Run the Test Suite
@chapter How to Run the Test Suite

@c FIXME: 
Still to be written.

@c ##########################################################################
@node Results Collected on Various Switches
@chapter Results Collected on Various Switches

@c FIXME: 
Still to be written.

@c ##########################################################################
@bye


@c  LocalWords:  gnudd titlepage iftex texinfo CERN timestamping smallexample
@c  LocalWords:  LocalWords ietf timestamp misc timestamps ttstamp onestamp
@c  LocalWords:  recvmsg cmsg recv SIOCSHWTSTAMP hwstamp config setsockopt xmit
@c  LocalWords:  bitmask TIMESTAMPNS struct timespec timeval ktime memset linux
@c  LocalWords:  sizeof syststamp tstamps hwtstamps hwtstamp shhwtstamps tstamp
@c  LocalWords:  subsubheading skbuff getnstimeofday shtx inline Ohly sockglue
@c  LocalWords:  RCVTSTAMP RCVTSTAMPNS nano ohwr Gigabit itemx documentlanguage
@c  LocalWords:  documentencoding setfilename settitle afourpaper finalout http
@c  LocalWords:  paragraphindent setchapternewpage Alessandro Rubini rubini
@c  LocalWords:  itemize factorized funcs HOWTO loopback multidump swflood
@c  LocalWords:  logfile stdout
